0

When I run the following code, why do I get unhandled promise rejection warning?

async function load() {
  throw new Error('error');
}

async function main() {
  const promise = load();

  await new Promise(resolve => setTimeout(resolve, 5000));

  try {
    await promise;
  } catch (e) {
    console.log('caught error', e);
  }
}

main();

This is the output:

jkim@dev-jkim test $ node index.js
(node:25276) UnhandledPromiseRejectionWarning: Error: error

Since await promise is around a try-catch, I'm confused why my try-catch isn't catching the error. I guess it's something to do with the setTimeout since the following code works:

async function load() {
  throw new Error('error');
}

async function main() {
  const promise = load();
  try {
    await promise;
  } catch (e) {
    console.log('caught error', e);
  }
}

main();
jkim@dev-jkim test $ node index.js
caught error Error: error

What is going on here? If promise rejections are not handled by the end of the current tick, does it automatically result in a unhandled promise rejection warning?

(I'm on node v10.16.3)

4

2 回答 2

2

If promise rejections are not handled by the end of the current tick, does it automatically result in a unhandled promise rejection warning?

Yes. A Promise must have a rejection handler attached to it at the moment it rejects, or the rejection will count as unhandled. If you attach the rejection handler later, such as after a

await new Promise(resolve => setTimeout(resolve, 5000));

the load Promise has rejected by the time the interpreter gets to the

try {
  await promise;
} catch (e) {

so, although the rejection can be caught with .catch, it wasn't caught by anything at the moment of rejection, resulting in the warning.

Best practice for this sort of thing is to always attach a rejection handler immediately - whether that means .catch, or inside a try/catch, or a Promise.all, or returning the Promise for the caller to handle.

于 2021-05-08T02:24:46.653 回答
0

The function load() throws an Error. When an error is thrown while a Promise is being handled, the Promise is rejected. Now, if the Error load() threw is not caught then, a UnhandledPromiseRejectionWarning is thrown by JS

A better Illustration of your code is:

function load() {
    console.log("hello after some time");
}

const foo = new Promise((resolve, reject) => {
    setTimeout(resolve, 5000);
})
.then(() => { load(); })
.catch((e) => { console.log(`Caught Error: ${e}`)});
于 2021-05-08T02:24:39.457 回答