How do I handle errors with promises?

54,809

Solution 1

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.

Solution 2

If you're using the async/await syntax, you can just use the regular try-catch syntax for error handling.

// your promise function
const myFn = function(param){
  return new Promise(function(resolve, reject){
      if (someLogic()) {
          resolve(someValue);
      } else {
          reject('failure reason');
      }
  });
}

// Define the parent function as an async function
async function outerFn(param) {
    try {
        // Wait for the promise to complete using await
        const result = await myFn(param)
        // business logic with result
    } catch (e) {
        //error handling logic
    }
}
Share:
54,809
Benjamin Gruenbaum
Author by

Benjamin Gruenbaum

Hi, I'm Benjamin 👋 You can find me here or if you need to reach me. At my day job I work at Microsoft on JavaScript development infrastructure in WiCD. Before that I was in Testim.io working on automating test automation and empowering QA developers Before that I worked on distributed algorithms and platforms for the webrtc based Peer5 P2P CDN, before that I wrote ran the core dev team at TipRanks writing csharp and javascript. I also do a bit of open source, here are some projects I am involved with: Node.js node.js platform - core collaborator. Bluebird bluebird core team member and maintainer. MobX mobx core team. Sinon.JS sinon.js team member. If you want to get involved in Node.js (at any capacity, no experience required) please do reach out. I promise you don't need perfect English, l33t coding skills or to be a "bro" to fit in (but those are welcome too). My email is written in the node home page. If you have an interesting use case for async-iterators/generators in Node.js - we're interested in talking in particular :) I have gold tags in promise javascript and a few others because I've spent a year answering as many promises questions as I could back then. If you're building something cool with promises please don't hesitate to reach out. I hereby release any code, test or multimedia content written in any answer and/or question by me in StackOverflow and anywhere else in the Stack Exchange network as public domain. No acknowledgement is required (although it is appreciated).

Updated on December 07, 2020

Comments

  • Benjamin Gruenbaum
    Benjamin Gruenbaum over 3 years

    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?