-1

Let's say I have 3 functions with promises:

function1().then(() => {
  function2().then(() => {
    function3().then(() => {      
    })
  })
}).catch((err) => {
  console.log(err);
})

Would I be able to catch the error returned by any of the 3 functions? If not, what should I do in order to catch the errors returned by any of the functions' promises with one statement?

5
  • No, you will only catch errors in function1 because the other two aren't part of the same promise chain. Minimal example: Promise.resolve().then(() => { Promise.reject("whoops!") }).catch((err) => console.log(err)); Commented Jul 13, 2020 at 20:14
  • Is there a way that I can catch the errors with one statement? Commented Jul 13, 2020 at 20:15
  • Yes, make them all part of the same promise chain: Promise.resolve().then(() => Promise.reject("whoops!")).catch((err) => console.log(err)); Commented Jul 13, 2020 at 20:15
  • Simplest form: function1().then(function2).then(function3).then(() => { /* do whatever */ }).catch(console.log); Commented Jul 14, 2020 at 0:51
  • Even better, Promise.resolve().then(function1).then(function2).then(function3).then(() => { /* do whatever */ }).catch(console.log); Commented Jul 14, 2020 at 3:18

3 Answers 3

1

Instead of calling and chaining them in the bodies, return the resulting promise and chain the .then clauses.

function1().then(() => {
  // TODO: Something.
  return function2();
}).then(() => { // <-- This `.then` waits until `function2` has finished executing
  // TODO: Something.
  return function3();
}).then(() => { // <-- This `.then` waits until `function3` has finished executing
  // TODO: Something.
}).catch((err) => {
  console.log(err);
});
Sign up to request clarification or add additional context in comments.

Comments

1

The simplest change is to just return the inner promises. That will cause their rejections to propagate upwards to the single .catch(), like this:

function1().then(() => {
  return function2().then(() => {
    return function3().then(() => {      
    })
  })
}).catch((err) => {
  console.log(err);
})

But, this successive nesting of promises is less-than-ideal (some would call it an anti-pattern). If you really want things sequenced these days and you're using a modern JS environment, then you would sequence things and catch errors in one place with await:

async someFunction() {
    try {
        let val1 = await function1();
        let val2 = await function2();
        let val3 = await function3();
    } catch(e) {
        // catch any rejections from the above three `await` statements here
        console.log(e);
    }
}

Using await also makes it a lot easier to see the code flow and to gather results from multiple asynchronous calls in one scope.


Without await, you could also flatten your original code:

function1().then(() => {
    return function2().then(() => {
    })
}).then(() => {
    return function3().then(() => {      
    })
}).catch((err) => {
  console.log(err);
})

But, most people will consider the await implementation to be simpler.

Comments

0

You can eighter use async/await or then without nested:

function1().then(() => Promise.resolve(val1))
.then(() => Promise.resolve(val2))
 ...
}).catch((err) => {
  console.log(err);
});

With async/await:

try {
    await function1();
    await function2();
    ...
} catch(err) {
    console.log(error);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.