Search code examples
javascriptasynchronouspromiseunhandled-promise-rejection

What is UnhandledPromiseRejectionWarning: Error?


I've pasted two almost same codes with one little difference, one works just fine but the other gives UnhandledPromiseRejectionWarning.

async function promise () {
  return new Promise((resolve, reject) => {
    throw new Error();
    resolve();
    reject();
  })
}

promise().then((data) =>{console.log('then')}).catch((err)=>{console.log('from the catch')});

The output is :

> node index.js
from the catch

But for this case

function promise () {
  return new Promise(async (resolve, reject) => {
    throw new Error();
    resolve();
    reject();
  })
}

promise().then((data) =>{console.log('then')}).catch((err)=>{console.log('err')});

The output is something like this

> node index.js
(node:98195) UnhandledPromiseRejectionWarning: Error
    at /home/parthiv/Projects/exp/index.js:47:11
    at new Promise (<anonymous>)
    at promise (/home/parthiv/Projects/exp/index.js:46:10)
    at Object.<anonymous> (/home/parthiv/Projects/exp/index.js:53:1)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32)
    at Function.Module._load (internal/modules/cjs/loader.js:790:12)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
    at internal/main/run_main_module.js:17:47
(Use `node --trace-warnings ...` to show where the warning was created)
(node:98195) 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(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:98195) [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.

Can someone explain this behaviour of an async function inside the promise ?


Solution

  • You've passed an async function into a Promise constructor, which is not the right thing to do. The return value of the async function is what is unhandled.

    The Promise constructor is designed for synchronous usage, and it completely disregards its return value. If you throw in the function you pass to a Promise constructor, the Promise constructor will return a rejected promise; that's the behavior you see in your first example. If the function returns a value, even a Promise, it won't matter: the value is discarded.

    About the executor, it’s important to understand the following:

    • The executor return value is ignored.
    • If an error is thrown in the executor, the promise is rejected.

    async functions convert its return and throw calls to Promise resolution, but async functions always return a Promise. So in your second example, your throw results in a rejected Promise, which is then unhandled; the return value is discarded entirely as above. If it weren't for the UnhandledPromiseRejectionWarning, your throw new Error() would have no symptoms, and the promise your promise() returned would never resolve.

    If you want promise() to return a promise, you can just return the return value of the inner async function, or (even better) make promise() itself an async function. If you do need the resolve/reject calls, you can always return new Promise() from inside the function; whenever an async function or .then() handler returns a Promise, that return value is unwrapped.