Serg Vorfolomeev
Serg Vorfolomeev

Reputation: 23

simple UnhandledPromiseRejectionWarning

When I try to run this, i get "UnhandledPromiseRejectionWarning". But last "catch" received control anyway with correct "err" object. I have got two warnings:

UnhandledPromiseRejectionWarning

PromiseRejectionHandledWarning

If I comment "return delay(5000);" all works fine. Why does Node.JS handle "promiseErr" before I do that?

const delay = (ms: number) => new Promise(res => setTimeout(res, ms));

let promiseErr = new Promise( (resolve, reject) => {
    reject(new Error("__error__"));
});

let promiseOk = new Promise( (resolve, reject) => {
    resolve();
    });

promiseOk
    .then( () => {
        return delay(5000);
    })
    .then( () => {
        return promiseErr;
    })
    .then( () => {
        console.log("OK");
    })
    .catch( (err) => {
        console.log(`ERR ${err}`);
    });

program output

Upvotes: 1

Views: 141

Answers (1)

Benjamin Gruenbaum
Benjamin Gruenbaum

Reputation: 276506

You have a rejected promise asynchronously (after 5000ms). Node.js detects unhandled promises by looking at promises that were not handled synchronously or within a microtick (inside a then).

Since Node.js cannot know "for sure" when a promise rejection is unhandled at the moment it errors on the safe side and gives you the warning. It is generally better to add catch handlers to promise errors synchronously as much as possible.

You can suppress the warning by adding a .catch(() => {}) to promiseErr when you create it which will handle the exception:

var promiseErr = ...
promiseErr.catch(() => {}); // add a catch handler without changing the original

In general - the solution is to not write code in such an error prone way. If promiseOk or delay rejects (which Node has no way of knowing) - then the exception in promiseErr itself is indeed unhandeld - so this is not really a safe way to write code.

Upvotes: 1

Related Questions