0

How to handle your own generated errors together with library / unhandled exceptions in Javascript promises? The problem I'm facing is generated by the "catch-all" nature of the catch() method of promises.

For instance, I have the following code:

somePromiseFunction()
.then(result => {
    // External library or behaviour
    someCodeThatCanThrowExceptions()

    if (result.code === 1) {
        throw 'My own exception'
    }
})
.catch(err => {
    // how do I know if this is an exception I don't know or something
    // that I do want to actually handle?
});

Lots of things can go wrong in the then() chain, external libraries can throw exceptions and so on. For instance, I want to print "Generic error" when something like this happens.

But I also want to validate the code and exit early (like I'm doing in the example) and in this case actually print my own message "My own error".

How to handle both my "exit early" throws and all the different things than can go wrong during the execution of the code?

pistacchio
  • 56,889
  • 107
  • 278
  • 420
  • 1
    Is it enough to have code in the .catch that checks `if (err === 'My own exception')` followed by your custom handler, followed by an else with the general handler? – Nicholas Tower Oct 05 '17 at 19:11
  • Don't promote [this library](https://github.com/AlexanderMac/n-custom-errors), but it does what you need. Gives a possibility to register custom errors and check that thrown error is a custom error. – alexmac Oct 05 '17 at 19:31
  • [Never `throw` strings.](https://stackoverflow.com/a/26020867/1048572) – Bergi Oct 05 '17 at 19:59
  • One approach, which I generally do, is don't throw exceptions for expected errors. Exceptions in JS are generally truly exceptional behavior. If you expect a case enough to explicitly be checking for a code of some kind, it's not exceptional and should just be treated like a result that happens to have a failure result. – loganfsmyth Oct 05 '17 at 21:51

1 Answers1

1

In your specific case, you are throwing a simple string exception, so you would have to look at the value.

function go() {
  return new Promise(function(resolve, reject) {
    throw 'My Exception';
  });
}

const x = go()
  .then(function() {

  })
  .catch(function(ex) {
    if (ex === 'My Exception') {
      alert('It was mine');
    }
  });

If you create more specialised exceptions, you can test the type, rather than the exact string. Here is an example with an exception that follows the window.Error pattern (i.e. it has a name and a message) that can be type tested:

var MyError = (function() {
  function MyError(message) {
    this.message = message;
    this.name = 'MyError';
  }
  return MyError;
}());

function go() {
  return new Promise(function(resolve, reject) {
    throw new MyError('Something went wrong');
  });
}

const x = go()
  .then(function() {

  })
  .catch(function(ex) {
    if (ex instanceof MyError) {
      alert('It was mine');
    }
  });

This has the benefit of decoupling your message from your test to determine if it is your error or not.

Fenton
  • 241,084
  • 71
  • 387
  • 401