4

以这个 URL 为例:https ://api.eveonline.com/eve/CharacterID.xml.aspx?names=Khan

使用xml2js node.js 模块,您可以解析该 XML,尽管它看起来并不漂亮:

var CharacterID = response.eveapi.result[0].rowset[0].row[0].$.characterID;

该应用程序在运行 2 周后崩溃,这一切都是因为未定义行集 [0] 。在此之前它崩溃了,因为eveapi没有定义。说真的,我的if-else是否必须像这样只是为了防止服务器由于愚蠢的未定义对象错误而崩溃?

 if (!response.eveapi || 
     !response.eveapi.result[0] || 
     !response.eveapi.result[0].rowset[0] || 
     !response.eveapi.result[0].rowset[0].row[0]) {
            return res.send(500, "Error");

除了适用的明显错误处理之外,未定义错误if (err) return res.send(500, "Error");的一般做法是什么?

4

3 回答 3

4

我为这种东西写了一个库,叫做 dotty ( https://github.com/deoxxa/dotty )。

在你的情况下,你可以这样做:

var dotty = require("dotty");

var CharacterID = dotty.get(response, "eveapi.result.0.rowset.0.row.0.$.characterID");

在路径不可解析的情况下,它只会返回未定义。

于 2013-06-28T08:03:37.517 回答
3

正如您所发现的,未定义本身并不是错误,但使用未定义作为数组/对象是错误的。

x = {'a': { 'b': { 'c': { 'd': [1,2,3,4,5]} } } } ;
try { j = x.a.b.c.e[3] } catch(e) { console.log(e); }

印刷

[TypeError: Cannot read property '3' of undefined]

这向我表明,try/catch 可以与您的代码一起使用以返回错误代码,如果需要,还可以返回错误文本(或者只是将错误文本粘贴在 console.log、数据库或本地文件中)。

在你的情况下,这可能看起来像:

var CharacterID; // can't define it yet

try {
  CharacterID = response.eveapi.result[0].rowset[0].row[0].$.characterID;
} catch(e) {
// send description on the line with error
  return res.send(500, "Error: NodeJS assigning CharacterID: "+e); 
// return res.send(500, "error");  use this one if you dont want to reveal reason for errors
}

// code here can assume CharacterID evaluated.  It might still be undefined, though.
于 2013-06-28T06:17:49.043 回答
1

也许这个功能有帮助?

function tryPath(obj, path) {
    path = path.split(/[.,]/);
    while (path.length && obj) {
        obj = obj[path.shift()];
    }
    return obj || null;
}

对于您将使用的代码:

if (tryPath(response,'eveapi.result.0.rows.0.row.0') === null) {
  return res.send(500, "Error");
}

jsFiddle示例
jsFiddle相同的示例,但作为扩展Object.prototype

于 2013-06-28T08:23:44.907 回答