Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to catch uncaught exception in Promise

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?

like image 758
John Avatar asked Jan 17 '15 16:01

John


People also ask

How do you catch an error on a Promise?

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 is uncaught in Promise error?

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.

Can we use try catch inside Promise?

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.

Does catch return a Promise?

catch() The catch() method returns a Promise and deals with rejected cases only. It behaves the same as calling Promise.


2 Answers

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.

like image 69
Benjamin Gruenbaum Avatar answered Sep 21 '22 13:09

Benjamin Gruenbaum


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: either return your promise to someone else, or if the chain ends with you, call done to terminate it. Terminating with catch is not sufficient because the catch 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.

like image 34
JLRishe Avatar answered Sep 20 '22 13:09

JLRishe