2

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?

2
  • 1
    You're throwing an error while in the client.find callback. bloomjs probably has a catch around the call to the callback that calls it again with an error indication. Commented May 1, 2015 at 17:17
  • It might be happening in one of the two lines where you return your err variable Commented May 1, 2015 at 17:19

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.