一尘不染

节点JS忽略未定义的检查

node.js

我正在开发一个NodeJs应用程序,该应用程序从FB接收一个事件并将其放入本地数据库。对于api查询首页中的每个事件,除最后一个事件外,一切正常。

我收到以下错误:

[2016年12月1日,下午1:48:39]
TypeError:无法读取IncomingMessage上未定义的属性“名称”。(/home/node/virgo/app.js:217:32)在IncomingMessage.emit(events.js:129:20)在_stream_read.js:907:16在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();
}

有关中断事件,请参见graph api资源管理器:Graph
API

场次编码:1682486658666506

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


阅读 182

收藏
2020-07-07

共1个答案

一尘不染

而不是https.request尝试使用request

它将为您提供解析的JSON,而您无需手动进行。

如果您希望像手动操作那样手动操作,请记住将其包装var json = JSON.parse(resultBody);在try /
catch块中(或使用tryjson),因为JSON.parse不能在try
/ catch之外的未知数据上使用-可能引发异常。

另外,不要在路由处理程序中打开数据库连接。您应该打开一次连接,然后在处理程序中使用它。。

现在要连接到数据库,但你继续连接回调外,让您从开始的所有行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.data不是数组,何时json.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为a
时,可能失败非空数组,但json.photos.data[json.photos.data.length-1].images[0].source未定义。

如您所见,这里有很多假设。如果不满足这些假设,则代码将失败。

2020-07-07