Search code examples
javascriptfetches6-promise

If you have a promise inside a promise, do you need two catch?


For example, making two calls with fetch() (second one inside the .then()), do you need two .catch() or only the outside one is enough?

I have tried to replicate but couldn't so far.

b = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('Solving...');
    resolve('solved');
  }, 3000);
})
  .then(() => {
    new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log('Rejecting...');
        reject('error');
      }, 1000);
    })
      .then(() => null)
      .catch((error) => {
        console.log('Catching error inside.');
        console.log(error);
      });
  })
  .catch((error) => {
    console.log('Catching error outside.');
    console.log(error);
  });

This works, but if I remove the inner catch() I get Unhandled promise rejection error

Solving...
Rejecting...
(node:73650) UnhandledPromiseRejectionWarning: error
(node:73650) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:73650) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Solution

  • You need to return the promise in then blocks to be able to catch them in one chain:

    b = new Promise((resolve, reject) => {
         setTimeout(() => {
           console.log('Solving...');
           resolve('solved');
         }, 3000);
      })
      .then(() => {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            console.log('Rejecting...');
            reject('error');
          }, 1000);
        });
      })
      .then(() => null)      // You can get rid of this if you don't have anything to do here
      .catch((error) => {
        console.log('Catching error outside.');
        console.log(error);
      });
    

    This should also be the preferred way. Having nested chaining as you have in your code sample will make the code very hard to read.