-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Description
Seen with Bluebird 2.9.3.
The behavior below caused a programming error to become hidden, making debugging difficult. The done() method will terminate the application on a thrown error within a promise chain, but it might wait to do so for quite some time, even processing more promises. In the meantime, the application continues to run, generating all kinds of unexpected side effects - after all, we're already in an error state.
I'm aware that the whole thing is a-synchronous and that you cannot terminate the application immediately on an exception. However, it seems that arbitrarily long promise chains are still executed before the done() - they seem to overtake each other. I would at least expect some execution order to be preserved.
What happened in reality (below is a smaller example) is that an assertion error occurred within a promise chain that ended in .done(). After that, the application was in a state where it behaved wrongly and eventually caused another un-handled rejection. The un-handled rejection overtook the assertion error and only the rejection was shown, obscuring the real cause. Note that the rejection was quite far removed in terms of nodejs cycles.
The example below shows the problem
var Promise = require("bluebird");
// kill the process on unhandled rejections
Promise.onPossiblyUnhandledRejection(function(reason) {
// do some custom logging
console.log("possibly unhandled rejected Promise", reason);
process.exit(1);
});
Promise.resolve()
.then(function() {
// longer chain expected to give error long after the process is dead
// not because .done() but because of possibly unhandled rejection handler.
Promise.resolve()
.then(function() {
Promise.resolve()
.then(function() {
Promise.reject(new Error("unhandled rejection"));
});
});
// exception expected to terminate the process
throw new Error("unhandled thrown error which should end the process because of done()");
})
.done();Console output:
possibly unhandled rejected Promise [Error: unhandled rejection]Is this expected behavior?