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

Kirk Ouimet picture Kirk Ouimet · Jul 27, 2014 · Viewed 59.4k times · Source

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);
}

Answer

Qantas 94 Heavy picture Qantas 94 Heavy · Jul 27, 2014

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)).