We're using the Q promise library in our node API, but allow functions to be called via callbacks.
For example:
function foo(cb) {
Q.fcall(function () {
return true;
}).then(function (result) {
return cb(null, result);
}).catch(function (err) {
return cb(err, null);
});
}
When I run my mocha unit tests, if there is an exception in the callback, it results in the the callback being called twice.
For example:
var called = 0;
foo(function (err, res) {
called++;
console.log('err: ' + err);
console.log('res: ' + res);
console.log('called: ' + called);
throw Error(throw Error from foo!');
});
This gives the following result:
err: null res: true called: 1 err: Error: throw Error from foo! res: null called: 2
One approach we found was to do the following:
function foo2(cb) {
var _result, _err;
Q.fcall(function () {
return true;
}).then(function (result) {
_result = result;
}).catch(function (err) {
_err = err;
}).finally(function () {
_.defer(cb, _err, _result);
});
}
The idea was to have one place where the callback would be called and try to prevent developer errors by enforcing the defer to clear the call stack.
With this approach, our callback is called once, and any errors (or in our case, asserts) get handled directly by the caller.
Is there a better technique we can use? I feel like this is a pretty common scenario, so I'd imagine there exists a cleaner solution...