Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catching Errors in JavaScript Promises with a First Level try ... catch

So, I want my first level catch to be the one that handles the error. Is there anyway to propagate my error up to that first catch?

Reference code, not working (yet):

Promise = require('./framework/libraries/bluebird.js');  function promise() {     var promise = new Promise(function(resolve, reject) {         throw('Oh no!');     });      promise.catch(function(error) {         throw(error);     }); }  try {        promise(); } // I WANT THIS CATCH TO CATCH THE ERROR THROWN IN THE PROMISE catch(error) {     console.log('Caught!', error); } 
like image 992
Kirk Ouimet Avatar asked Jul 27 '14 02:07

Kirk Ouimet


People also ask

Can you use try catch in promise?

You cannot use try-catch statements to handle exceptions thrown asynchronously, as the function has "returned" before any exception is thrown. You should instead use the promise. then and promise. catch methods, which represent the asynchronous equivalent of the try-catch statement.

How do you catch errors in promise chains?

There are two ways in which you can handle errors in your promise chain, either by passing an error handler to then block or using the catch operator.

What happens if I don't catch a promise?

A promise is just an object with properties in Javascript. There's no magic to it. So failing to resolve or reject a promise just fails to ever change the state from "pending" to anything else. This doesn't cause any fundamental problem in Javascript because a promise is just a regular Javascript object.

What does try catch do in JavaScript?

JavaScript try and catch The try statement allows you to define a block of code to be tested for errors while it is being executed. The catch statement allows you to define a block of code to be executed, if an error occurs in the try block.


2 Answers

You cannot use try-catch statements to handle exceptions thrown asynchronously, as the function has "returned" before any exception is thrown. You should instead use the promise.then and promise.catch methods, which represent the asynchronous equivalent of the try-catch statement. (Or use the async/await syntax noted in @Edo's answer.)

What you need to do is to return the promise, then chain another .catch to it:

function promise() {     var promise = new Promise(function(resolve, reject) {         throw('Oh no!');     });      return promise.catch(function(error) {         throw(error);     }); }  promise().catch(function(error) {     console.log('Caught!', error); }); 

Promises are chainable, so if a promise rethrows an error, it will be delegated down to the next .catch.

By the way, you don't need to use parentheses around throw statements (throw a is the same as throw(a)).

like image 186
Qantas 94 Heavy Avatar answered Sep 23 '22 06:09

Qantas 94 Heavy


With the new async/await syntax you can achieve this. Please note that at the moment of writing this is not supported by all browsers, you probably need to transpile your code with babel (or something similar).

// Because of the "async" keyword here, calling getSomeValue() // will return a promise. async function getSomeValue() {   if (somethingIsNotOk) {     throw new Error('uh oh');   } else {     return 'Yay!';   } }  async function() {   try {     // "await" will wait for the promise to resolve or reject     // if it rejects, an error will be thrown, which you can     // catch with a regular try/catch block     const someValue = await getSomeValue();     doSomethingWith(someValue);   } catch (error) {     console.error(error);   } } 
like image 31
Edo Avatar answered Sep 22 '22 06:09

Edo