Max Heiber
Max Heiber

Reputation: 15502

Why is "unhandled promise rejection" a thing?

I understand when the UnhandledPromiseRejectionWarning error happens. What I don't understand is why the the spec was written in such a way as to allow this behavior.

For example, the following code is bad, if callApi() rejects than we get the UnhandledPromiseRejectionWarning error in Node a similar error in each browser:

class A {
    constructor () {
        this._stuff = Promise.reject(Error('oops'))
    }
    getStuff () {
        return this._stuff
    }
}

const a = new A()

setTimeout(() => {
    a.getStuff().catch(err => console.log('I caught it!'))
}, 100)

But why?! I tend to thing of promises as abstracting over when stuff happens. That's exactly how the promise acts if callApi() is successful: the caller of getStuff() will get the stuff when the data is available.

But the rejection case doesn't work the same way. What I'd expect to happen (if I hadn't been burned by this before) is for the burden of handling the error to fall to the caller of getStuff. That's not how it works, but why?

Upvotes: 0

Views: 694

Answers (1)

jfriend00
jfriend00

Reputation: 707318

The detection of an unhandled promise rejection is imperfect in node.js. I don't know exactly how it works internally, but if you don't have a .catch() in a promise chain and that promise rejects, even if you assign it to a variable and then later add a .catch() to it, then it will give you the "unhandled rejection warning".

In your specific case, it is probably because you got back to the event loop with a rejected promise that wasn't caught - your .catch() is only added later on a subsequent event. There's no way for the node.js interpreter to know that you're going to do that. It sees that an event finished executing and a rejected promise was not handled so it creates the warning.

To avoid the warning, you will have to code it differently. You don't really show a real world use so we can see what you're trying to accomplish to make a specific suggestion. As with other types of things like this, the best way to handle it varies depending upon the real world use case.


If you're asking why an unhandled rejection is a warning at all, then that's because it can be a serious error and if there was no warning, then it would simply fail silently and the developer would never be the wiser. It's very much akin to an unhandled exception in synchronous code. That's a serious error and aborts the program. node.js has been notifying for awhile that an unhandled rejection may get the same treatment in the future. For now, it's just a warning.

Upvotes: 1

Related Questions