JS uncaught error when Promise finally is used in function

Viewed 529

Here is JS code:

function createPromise() {
  const result = new Promise((resolve, reject) => {
    setTimeout(() => {
      reject(new Error('my error'));
    }, 2000);
  });
// uncomment this to get error
//  result.finally(() => {
//     console.log('finally before');
//  });

  return result;
}

function test() {
  createPromise()
    .then(() => {
      console.log('promise then');
    })
    .catch((error) => {
      console.log('promise catch:', error);
    })
    .finally(() => {
      console.log('promise finally');
    });
}

Its works properly and after executing I have in the console:

promise catch: Error: my error
promise finall

But after uncommenting:

result.finally(() => {
     console.log('finally before');
  });

In console I have uncaught exception:

finally before
promise catch: Error: my error
promise finally
Uncaught (in promise) Error: my error

Why is this happening and how to explain it?

1 Answers

The unhandled promise

Like .then and .catch, .finally returns a promise. But unlike .catch or .then with a second argument supplying an onrejection handler, finally does not fulfill the promise it returns if the previous promise in the chain becomes rejected.

So the expected output without the comments for the result promise is the same. But in addition there is the promise returned by .finally in createPromise that doesn't have a rejection handler. Hence the uncaught promise rejection error.

The .finally in function test is okay because the preceding catch clause fulfills the promise it returned so .finally won't reject the promise it returned.


More about onfinally

  • Generally a .finally clause passes through the result, or promise rejection reason, of the previous promise in a promise chain to the next promise in the chain.

  • However, if an onFinally handler throws an error or returns a rejected promise, the next promise in the chain is rejected for the same error or rejection reason provided by the handler - any data or rejection reason arriving from previous promises in the chain is effectively discarded.

Related