Reputation: 1837
When using a third party library that doesn't depend on the async
library, somehow handling an error in the results callback calls an arbitrary callback inside one of the parallel tasks.
eg.
var async = require('async'),
bloomjs = require('bloom-js');
var client = new bloomjs.Client({url: "http://localhost:3005/api"});
async.parallel([function (cb) {
console.log('callback1');
client.find('usgov.hhs.npi', '1558490003', function (err, results) {
console.log('callback2');
if (err) return cb(err);
cb(results);
});
}], function (err, results) {
console.log('callback3');
throw "hello";
if(err) return console.dir(err);
console.dir(results);
});
generates the output
callback1
callback2
callback3
callback2
/Users/untoldone/Source/async-demo/node_modules/async/lib/async.js:30
if (called) throw new Error("Callback was already called.");
^
Error: Callback was already called.
at /Users/untoldone/Source/async-demo/node_modules/async/lib/async.js:30:31
at /Users/untoldone/Source/async-demo/node_modules/async/lib/async.js:251:21
at /Users/untoldone/Source/async-demo/node_modules/async/lib/async.js:575:34
at /Users/untoldone/Source/async-demo/demo.js:9:21
at /Users/untoldone/Source/async-demo/node_modules/bloom-js/src/bloom.js:117:18
at IncomingMessage.<anonymous> (/Users/untoldone/Source/async-demo/node_modules/bloom-js/src/bloom.js:219:22)
at IncomingMessage.EventEmitter.emit (events.js:117:20)
at _stream_readable.js:920:16
at process._tickCallback (node.js:415:13)
It seems the callback2 is somehow being used to handle an exception in callback3. But given bloomjs
never uses the async
library, I have no idea how this is possible. Thoughts?
Upvotes: 2
Views: 142
Reputation: 782693
I suspect that inside bloomjs.Client.find
, the callback code contains something like this:
try {
callback(false, result);
} catch (e) {
callback(e, result);
}
So when your callback throws the hello
error, this gets caught by the above code, and re-calls the client.find
callback. This would again call cb()
, but async.js
detects this loop and signals its own error.
Upvotes: 2