-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unhandled rejection overtakes synchronous exception through done() #471
Comments
The problem is in async.js using setTimeout to throw the error, if available. By that time the possibly unhandled rejection has already happened and the process will exit. Maybe it can be fixed by a patch that rethrows both synchronously and asynchronously. |
We also have this: Promise.setScheduler(function(callback) {
setImmediate.apply(null, [callback]);
}); I would at least have expected that to be used also for .done(). But I agree that throwing synchronously would be even better. EDIT: note that reproducing the error was done without this scheduler so in that sense it does not matter. |
I want to throw synchronously but if the application recovers from the exception (e.g. always in browser and sometimes in node if there is domain or uncaughtException handler that doesn't exit process), it will leave bluebird in inconsistent state |
Would that matter once you've made a programmer error? |
In practice, yes.. just open the console of any website, it's full of uncaught errors and the applications appear to be keep working just fine. |
Could we make it an option, then? So we can have a sync exception server-side, or while not in production? |
What if in node it did the same as event emitters... write stack trace to stderr and exit immediately? shouldn't that be effectively the same as throwing synchronously but without the risk that the application recovers? |
Yes that would be nice. But in that case I would expect a handler similar to onPossiblyUnhandledRejection() so that I can flush the logs. |
You mean |
Good point |
No wait, that means I cannot log the exception to my own logging system anymore and also I cannot flush the logs because process.on("exit" only allows sync actions. |
So if you need to do async stuff before the exception can be thrown, it will not be any different from the status quo because while you are waiting for the logs to flush, the unhandled rejection handler will be called and call process.exit |
@rogierschouten 3.0.0 will be soon released 2-4 weeks, do you have any input? I think you can synchronously flush logs with Otherwise this will be left as (as it doesn't change anything if you need to flush logs asynchronously) and the next time it can be changed is 4.0. |
Hi Petka, I agree with you, you can throw synchronously.Thank you. Rogier |
- Unhandled rejection: petkaantonov/bluebird#471
- Unhandled rejection: petkaantonov/bluebird#471
- Unhandled rejection: petkaantonov/bluebird#471
Fixed in 3.0 release |
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
Console output:
Is this expected behavior?
The text was updated successfully, but these errors were encountered: