Node.js Error Handling - How to deal with undefined values ​​that cause errors

Take this URL, for example: https://api.eveonline.com/eve/CharacterID.xml.aspx?names=Khan

Using the xml2js node.js module, you can parse this XML, although it does not look pretty:

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

The application crashed after two weeks of operation because rowset [0] was undefined. Before that, it crashed because eveapi was not defined. Seriously, should my if-else really be such as to prevent a server crash due to dumb undefined object errors?

  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"); 

Besides the obvious error handling, if (err) return res.send(500, "Error"); where applicable, what is the common practice of undefined errors?

+4
source share
3 answers

As you have discovered, undefined alone is not an error, but using undefined as an array / object is an error.

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

prints

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

This tells me that try / catch can be used with your code to return an error code and, if desired, an error text (or just paste the error text into console.log, a database, or a local file).

In your case, it might look like this:

 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. 
+3
source

I wrote a library for this kind of thing called dotty ( https://github.com/deoxxa/dotty ).

In your case, you can do this:

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

In the event that the path is not resolvable, it will simply return undefined.

+4
source

Perhaps this feature helps?

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

For your code you will use:

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

jsFiddle example
jsFiddle is the same example, but as an extension to Object.prototype

+1
source

Source: https://habr.com/ru/post/1488625/


All Articles