Node JS忽略未定义的检查

时间:2016-12-01 14:04:32

标签: javascript json node.js facebook-graph-api https

我正在开发一个NodeJs应用程序,该应用程序从FB获取事件并将其放入本地数据库。对于api查询的第一页中的每个事件,这都很顺利,除了最后一个。

我收到以下错误:

  

[2016年12月1日,下午1:48:39] TypeError:无法读取属性'name'   未定义的       在IncomingMessage。 (/home/node/virgo/app.js:217:32)       在IncomingMessage.emit(events.js:129:20)       在_stream_readable.js:907:16       at process._tickCallback(node.js:372:11)

之后
console.log(resultBody);

代码:

function addFBEvent(facebookId){
console.log("getting event: " + facebookId);

var options = {
    hostname: 'graph.facebook.com',
    port: 443,
    path: '/v2.8/'+facebookId+'?fields=name,description,start_time,end_time,place,photos{images}&access_token={INSERT API ACCESS CODE HERE}',
    method: 'GET'
};

https.request(options, function(res2) {
    var resultBody = "";
    res2.setEncoding('utf8');
    res2.on('data', function (chunk) {
        resultBody = resultBody + chunk;
    });

    res2.on('end', function () {
        dbConnection = sql.createConnection({
                                host     : settings.dbHost,
                                user     : settings.dbUser,
                                password : settings.dbPassword
                            });

        dbConnection.connect(function(err){
                if(!err) {
                    console.log("Database is connected ... nn");
                } else {
                    console.log("Error connecting database ... nn");
                }
        });

        var json = JSON.parse(resultBody);

        console.log(resultBody);

        if (json != undefined){
            var eventName = json.name;
            var eventStart = json.start_time;
            var eventEnd = json.end_time;
            var eventDescription = json.description;
            var eventPlace = json.place.name;
            var eventPoster = json.photos.data[json.photos.data.length-1].images[0].source;
            var eventId = json.id;

            console.log("name: " + eventName + ", start: " + eventStart + ", end: " + eventEnd + ", place: " + eventPlace + ", Poster: " + eventPoster);
            //console.log("Description: " + eventDescription);

            dbConnection.query('INSERT INTO SVVirgo.activities(title, description, image, start, end, price, location, facebook) VALUES ("'+eventName+'","'+eventDescription+'","'+eventPoster+'","'+eventStart+'","'+eventEnd+'",0,"'+eventPlace+'","'+eventId+'")', function (err, result){

            });
        }

        dbConnection.end();
    })
}).end();
}

请参阅图表api资源管理器了解中断事件:Graph API

活动代码:1682486658666506

我试过没有运气捕获未定义的json对象,我也尝试使用此解决方案验证json:Stackoverflow validate JSON javascript

1 个答案:

答案 0 :(得分:1)

而不是https.request尝试使用request

它将为您提供已解析的JSON,您不必手动执行此操作。

如果你想像你一样手动完成,那么记得将var json = JSON.parse(resultBody);包装在try / catch块中(或使用tryjson),因为JSON.parse不能用于未知try / catch之外的数据 - 它可以抛出异常。

另一件事是,不要在路由处理程序中打开数据库连接。您应该打开一次连接,然后在处理程序中使用它。有关详情,请参阅this answer

现在您正在连接到数据库,但是您继续在连接回调之外,因此在建立数据库连接之前运行从var json = JSON.parse(resultBody); 开始的所有行。

此外,错误可能不是因为json未定义,而是因为json.place未定义。

你可以改变这个:

var eventPlace = json.place.name;

到此:

var eventPlace = json.place && json.place.name;

在访问json.photos之前,您还必须先检查json.photos.data,然后在对待json.photos.data之前测试if (json.photos && Array.isArray(json.photos.data)) { // ... } 是否为数组(您可以执行以下操作:

json.photos.data[json.photos.data.length-1].images[0].source

基本上,在访问它们之前,您需要确保这些值是您希望它们的值。例如访问:

json
未定义json.photos,未定义json.photos.data,未定义json.photos.datajson.photos.data.length不是数组时,json.photos.data[json.photos.data.length-1]json.photos.data[json.photos.data.length-1].images时,

会失败零,未定义json.photos.data[json.photos.data.length-1].images时,json.photos.data[json.photos.data.length-1].images未定义时,json.photos.data[json.photos.data.length-1].images不是数组时,json.photos.data[json.photos.data.length-1].images[0].source是数组但是它是空的,或者何时{{1}}是非空数组,但{{1}}未定义。

正如您所看到的,您在这里做了很多假设。如果不满足这些假设,代码将失败。