How to catch an exception thrown in Promise

Is there a 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 die silently without error. Nothing in firebug.

My question is: if I am wrong and forgot to catch, is there a way to catch it globally?

+53
javascript promise exception
Jan 17 '15 at 16:39
source share
5 answers

Most promise implementations do not currently provide the type of functionality you are referring to, but a number of third-party promise libraries (including Q and bluebird ) provide a done() method that will capture and repair any uncaught errors by printing them to the console.

( Edit: see Benjamin Gruenbaum answer for a question about Bluebird functions for handling exceptions)

So, if you have this, you just need to follow the rule that any promise you use must be returned or completed with .done() :

 pr.then(function(result){ console.log(result); }) .done(); 

For a quote from the Q API link:

Golden rule of use done vs. then : either return your promise to someone else, or if the chain ends, call done to complete it. Finishing with catch not enough, as the catch handler may throw an error itself.

I understand that this still requires additional work, and you can still forget to do it, but this is an improvement over the need for .catch() and explicitly handle every error, especially for the reason mentioned above.

+15
Jan 17 '15 at 17:22
source share

An update, native promises is now performed on most browsers:

 window.addEventListener("unhandledrejection", function(err, promise) { // handle error here, for example log }); 



We just discussed it the other day.

Here is how you would do it with bluebird:

 window.onpossiblyunhandledexception = function(){ window.onerror.apply(this, arguments); // call } window.onerror = function(err){ console.log(err); // logs all errors } 

With Bluebird, you can also use Promise.onPossiblyUnhandledRejection . Requests for done not needed, since the library detects an unhandled deviation, unlike Q (UPDATE 2016 - now I wrote the code for Q, and he does it).

As for native promises - they will eventually be reported either in window.onerror or in a new handler, but the specification process has not been completed yet - you can follow this here .

+15
Jan 17 '15 at 10:24
source share

In Node.js you can use:

 process.on('unhandledRejection', (reason, promise) => { console.error(`Uncaught error in`, promise); }); 
+3
Dec 30 '16 at 10:52
source share

If you write code that can be executed both in the browser and in the Node.js environment, you can wrap your code in a self-executing function, like this:

 var isNode = (typeof process !== 'undefined' && typeof process.on !== 'undefined'); (function(on, unhandledRejection) { // PUT ANY CODE HERE on(unhandledRejection, function(error, promise) { console.error(`Uncaught error in`, promise); }); // PUT ANY CODE HERE })( isNode ? process.on.bind(process) : window.addEventListener.bind(window), isNode ? "unhandledRejection" : "unhandledrejection" ); 

What happens if you use this code:

  • If you run it in Node.js, your handler will be bound to the process object and will be executed if you have an uncaught exception in the promise.

  • If you run it in a browser environment, your handler will be attached to the window object and will be executed when you have an uncaught exception in the promise and your browser supports the unhandledrejection event.

  • If you run it in a browser environment without unhandledrejection support, you will not be able to catch your uncaught exception, and your unhandledrejection event unhandledrejection will never be launched, but you will not get any errors if there are no exceptions thrown.

+2
Jul 19 '17 at 15:23
source share

If you are using native Promise, this is pretty simple.
You only need .catch reject some of them.

 ajax(request).catch(function(rejected){ console.log(rejected); }); 

If I do not catch him somewhere, the neutralized promise will continue to show. But if I catch him somewhere ...

0
Jan 05 '16 at 2:59
source share



All Articles