Reputation: 560
While doing some work I saw "uncaught exception" errors reported in Firebug appearing at seemingly random moments. The exceptions were thrown inside promises in background.
At first I was surprised the errors were reported at all, as my understanding was that errors thrown in promises are simply caught and passed along the callbacks chain. But they are reported in post-Opera (=Chrome) too, and they don't kill the script, so that is a good thing then.
But in Opera exceptions are reported immediately while in Firefox there is some seemingly random delay (from a couple of seconds to half a minute). Why is that?
Here is a test code:
var p = new Promise( okLater );
p.then( kill );
function okLater( pass, fail ) {
setTimeout( pass.bind( this, "O.K." ), 10 );
}
function kill() {
console.log( "Killing" );
throw "Oops"
}
Upvotes: 1
Views: 136
Reputation: 664375
At first I was surprised the errors were reported at all, as my understanding was that errors thrown in promises are simply caught and passed along the callbacks chain
Yes, they are indeed. That promise you have created via p.then(kill)
is going to be rejected.
But we don't really want that. Exceptions that are silently ignored? Not a good idea. So we need unhandled rejection handling. An "unhandled exception" is a rejected promise that got no error handler attached. There is a bit of problem with identifying these, because the error handler could be attached later intentionally, and we wouldn't want that promise to be reported. Still, promise implementations have the capability to track their promises and report "possibly unhandled rejections", see this answer and How do I handle exceptions globally with native promises in node.js? for further details.
reported in Firebug appearing at seemingly random moments.
The moment you can be totally sure that a promise was rejected without a handler being attached is when it is garbage-collected. IIRC, Firefox has indeed implemented this hook, so these "random moments" would depend on the GC behaviour.
Upvotes: 2