A wrote a function, and then a unittest, and the unit test was good.
Then I called the function from my real project, and it failed!
I isolated the problem and thought I had found a bug in V8 (except after many years as a programmer I have I learnt it is never the compilers fault).
This was my output:
$ node bug.js Test good main: err=Not JSON
This is my simplified (faulty) code:
function callSomething(callback) { var rawdata = '{ "a":"1" }'; var jsondata; try { jsondata = JSON.parse(rawdata); callback(null,jsondata); } catch (e) { callback('Not JSON', null); } } function test() { callSomething(function(err,data) { if ( err ) console.log('Test bad: ' + err); console.log('Test good'); }); } function main() { var result = { outdata : {} }; callSomething(function(err,data) { if ( err ) { console.log('main: err=' + err); } else { result.outata.json = data; console.log('main: json=' + JSON.stringify(result.outdata.json)); } }); } test(); main();
How can the test not fail when main fails?
Well, here is the correct output
$ node nodebug.js Test good main: json={"a":"1"}
of the correct code main function:
function main() { var result = { outdata : {} }; callSomething(function(err,data) { if ( err ) { console.log('main: err=' + err); } else { // result.outata.json = data; result.outdata.json = data; console.log('main: json=' + JSON.stringify(result.outdata.json)); } }); }
The misnamed property caused an Error which was (unintentionally) caught, causing the anonymous callback function to be called once more, this time with err set, but to the wrong error.
It would have been better to write:
function callSomething(callback) { var rawdata = '{ "a":"1" }'; var jsondata; try { jsondata = JSON.parse(rawdata); } catch (e) { callback('Not JSON', null); return; } callback(null,jsondata); }
and the misnamed propery error would have crashed the program in the right place.
Conclusion
Don’t ever try more things than necessary. And if you need to try several lines, consider making separate try for each.
0 Comments.