Search code examples
javascriptnode.jses6-promise

How to differentiate between operational and programmer errors in promise chains?


So I want to know how to make sure that my Node application will crash if it comes upon a programmer error(undefined variable, reference error, syntax error...). However, if I am using promise chains then the final catch() will catch all possible errors including programmer errors.

For example:

PromiseA()
.then((result) => {
        foo.bar(); //UNDEFINED FUNCTION HERE!!!!!
        return PromiseB(result);
        })
.catch(
//handle errors here
)

Now the catch() statement will also catch the really bad error of an undefined function and then try to handle it. I need a way for my program to crash when it comes up against errors like these.

EDIT: I also just realized that even if I throw an error in the last catch it will just be consumed by the promise chain :-[. How am I supposed to deal with that?


Solution

  • Basically, what you want to do is to handle those errors that you can potentially recover from. These errors are usually something you throw in your code. For example, if an item is not found in a DB some libraries will throw an Error. They'll add a type property or some other property to differentiate the different type of errors.

    You can also potentially subclass the Error class and use instanceof to differentiate each error.

     class myOwnError extends Error {}
    

    Then:

    Prom.catch(err => {
       if(err instanceof myOwnError){ /* handle error here */ }
       else { throw err; }
    });
    

    If you want to avoid if/chains, you can use a switch on error.constructor:

    switch(err.constructor){
        case myOwnError:
        break;
        case someOtherError:
        break;
        default:
          throw err;
    }
    

    You can also use an a Map or regular objects by creating functions for each possible error and storing them. With a Map:

    let m = new Map();
    m.set(myOWnError, function(e){ /*handle error here*/ });
    m.set(myOtherError, function(e){ /*handle other error here*/ });
    

    Then just do:

    Prom.catch(err => {
       let fn = m.get(err.constructor);
       if(fn){ return fn(err); }
       else { throw err; }
    });