How do I handle errors with promises?

bluebird, error-handling, javascript, node.js, promise

Solution

Rule of Thumb

Whenever you have a doubt about how to do something with promises - think about the synchronous version.

try{
   var result = myFn(param);
   // business logic with result
} catch(e) {
    //error handling logic
}

This, at least to me looks a lot cleaner than a callback with a first parameter that is sometimes `null`.

The promises way is almost always very similar to the synchronous version of the problem:

myFn(param).then(function(result){
    // business logic with result
}).catch(function(e){
    //error handling logic
});

Where myFn would look something like when working with callbacks:

var myFn = function(param){
    return new Promise(function(resolve, reject){
        var calc = doSomeCalculation(param);
        if(calc === null) { // or some other way to detect error
            reject(new Error("error with calculation"), null);
        }
        someAsyncOp(calcN,function(err, finalResult){
            if(err) reject(err);
            resolve(finalResult);
        })
    });
};

Working with callbacks/nodebacks

This is only something you should have to do when working with callbacks, when working with promises it is a lot simpler, and you can do:

var myFn = function(param){
    var calc = doSomeCalculation(param);
    ...
    return someAsyncOp(calcN); // returning a promise.
}

Moreover, when working inside promise chains, you get throw safety:

myFn(param).then(function(calcN){
   // here, you throw to raise an error and return to resolve
   // new Promise should be used only when starting a chain.
}).catch(function(err){
    // handle error
}).then(function(){
   // ready to go again, we're out of the catch
});

Note, some libraries like Bluebird , RSVP and Q offer syntactic sugar and automatic promisification of methods so you rarely have to use `new Promise` yourself.

Also, consider reading this and that to learn more about promise error handling.

Problem

As a node programmer. I'm used to use "nodebacks" for handling errors in my code: ``` myFn(param, function(err, data) { if (err){ //error handling logic } else { // business logic } }); ``` When writing that function, I can do something like: ``` var myFn = function(param, callback){ var calc = doSomeCalculation(param); if(calc === null) { // or some other way to detect error callback(new Error("error with calculation"), null); } ... someAsyncOp(calcN,function(err, finalResult){ if(err) return callback(err, null); callback(null, finalResult); // the error is null to signal no error }); }; ``` How would I do this sort of error handling with promises?

Original source