Is there any way to globally catch all exceptions including Promise exceptions. Example:
window.onerror = function myErrorHandler(errorMsg, url, lineNumber) { alert("Error occured: " + errorMsg);//or any message return false; } var myClass = function(){ } var pr = new Promise(function(resolve, react){ var myInstance = new myClass(); myInstance.undefinedFunction(); // this will throw Exception resolve(myInstance); }); pr.then(function(result){ console.log(result); }); // i know right will be this: // pr.then(function(result){ // console.log(result); // }).catch(function(e){ // console.log(e); // });
This script will silently die without error. Nothing in firebug.
My question is if I do a mistake and forgot to catch it is there any way to catch it globally?
catch " around the executor automatically catches the error and turns it into rejected promise. This happens not only in the executor function, but in its handlers as well. If we throw inside a . then handler, that means a rejected promise, so the control jumps to the nearest error handler.
What does that log "Uncaught (in promise)" mean? It means that there was an error in one of our promises, but we did not write any code in order to handle that error and try to catch it.
If you throw an error inside the promise, the catch() method will catch it, not the try/catch. In this example, if any error in the promise1, promise2, or promise4, the catch() method will handle it.
catch() The catch() method returns a Promise and deals with rejected cases only. It behaves the same as calling Promise.
Update, native promises now do the following in most browsers:
window.addEventListener("unhandledrejection", function(promiseRejectionEvent) { // handle error here, for example log });
We were just discussing this the other day.
Here is how you'd do this with bluebird:
window.onpossiblyunhandledexception = function(){ window.onerror.apply(this, arguments); // call } window.onerror = function(err){ console.log(err); // logs all errors }
With Bluebird it's also possible to use Promise.onPossiblyUnhandledRejection
. The calls for done
are not needed as the library will detect unhandled rejection itself unlike Q (UPDATE 2016 - I now wrote code for Q and it does this).
As for native promises - they will eventually report to either window.onerror or a new handler but the specification process is not yet done - you can follow it here.
Most promise implementations don't currently provide the type of functionality you are referring to, but a number of 3rd-party promise libraries (including Q and bluebird) provide a done()
method that will catch and rethrow any uncaught errors, thus outputting them to the console.
(Edit: see Benjamin Gruenbaum's answer about Bluebird's features for handling uncaught exceptions)
So if you have that, you'd just need to follow the rule of thumb that any promise you use should either be returned or terminated with .done()
:
pr.then(function(result){ console.log(result); }) .done();
To quote from the Q API reference:
The Golden Rule of
done
vs.then
usage is: eitherreturn
your promise to someone else, or if the chain ends with you, calldone
to terminate it. Terminating withcatch
is not sufficient because thecatch
handler may itself throw an error.
I realize that this still requires a bit of extra work and you can still forget to do this, but it is an improvement over having to .catch()
and explicitly handle every error, especially for the reason pointed out above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With