Kalle Richter
Kalle Richter

Reputation: 8728

Are nested catches within promises required if then is used?

I think I got the idea of Promise, then and catch as well as nesting promises as shown in Are nested catches within promises required?. However, if I'm nesting promises and want to avoid inner catchs by returning the inner promise, then I'm having trouble to get the following not to crash because of the Error thrown in promise2:

function promise1(): Promise<string> {
  return new Promise(function(resolve, reject) {
    return promise2().then(promise2Result => {
      if(promise2Result !== "") {
        resolve("The value is "+promise2Result);
      }else {
        reject(new Error("promise2.then error"));
      }
    })
  });
}

function promise2(): Promise<string> {
  return new Promise(function(resolve, reject) {
    throw new Error("promise2 error");
  });
}

Chrome shows me an Unhandled Rejection (Error): promise2 error of the yarn development server started with yarn run start. It points to the Error thrown in promise2. Firefox debugger jumps to a random line outside of my code and displays nothing.

If I add a catch after promise2().then(...) the Error is caught.

How can I avoid the inner catch? And catch the Error from promise2 e.g. in a catch in

promise1()
  .then(value => alert(value))
  .catch(err => alert("err: "+err));

Wrapping every function body in a try-catch block is not an option as an inner .catch(...) is already more elegant.

The throwing of Error is a minimal example, of course, assume it occurs by accident and that the promise returned by promise2 is expected to do something useful and has a bug.

I'm looking for a principle which allows deeper nesting, e.g. with a promise2 which returns a promise3 which then accidentally might throw an error like promise2 does now.

Upvotes: 1

Views: 476

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370679

Your promise2 already returns a Promise, so there's no need for explicit construction of a Promise again. Instead, just chain off of the promise2, and if the value it resolves to is not OK, throw an error instead of calling reject. (Similarly, instead of calling resolve, return the expression you want the outer Promise to resolve to)

function promise1() {
  return promise2().then(promise2Result => {
      if (promise2Result !== "") {
        return "The value is " + promise2Result;
      } else {
        throw new Error("promise2.then error");
      }
    })
}

function promise2() {
  return new Promise(function(resolve, reject) {
    throw new Error("promise2 error");
  });
}

promise1()
  .catch(e => console.log(e.message));

Upvotes: 4

Related Questions