Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unhandled promise rejection even though I do handle it

I wrapped a request-promise-native call in a function that returns a promise.

import request from 'request-promise-native';
function requestWrapper(url) {
    return request(url)
        .then(data => {...})
        .catch(err => Promise.reject(err));
}

Simple right?

Now I'm using this function, and thenworks ok, but catch never catches the Promise.reject:

requestWrapper('http://some-url.com')
    .then(data => {...})
    .catch(err => console.log(err));

I never get to the call's catch! If I change the return statement in the catch of requestWrapper to this:

.catch(err => err)

or even this:

.catch(err => Promise.resolve(err))

to return a resolve, I get the error stack on the then of the requestWrapper call just as expected.

And node shouts:

(node:24260) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): ...
like image 591
Moshe Avatar asked Jan 23 '18 09:01

Moshe


People also ask

How do I get rid of unhandled Promise rejection?

If an error condition arises inside a promise, you “reject” the promise by calling the reject() function with an error. To handle a promise rejection, you pass a callback to the catch() function. This is a simple example, so catching the rejection is trivial.

What is unhandled Promise rejection error?

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(). (rejection id: 1) (node:31851) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated.

Why do Promises get rejected?

A Promise rejection indicates that something went wrong while executing a Promise or an async function. Rejections can occur in several situations: throwing inside an async function or a Promise executor/then/catch/finally callback, when calling the reject callback of an executor , or when calling Promise.

What happens if Promise is rejected?

catch " around the executor automatically catches the error and turns it into rejected promise. This happens not only in the executor function, but in its handlers as well. If we throw inside a . then handler, that means a rejected promise, so the control jumps to the nearest error handler.


2 Answers

if you are not getting that then do this workaround.

In order to handle rejections the following new events will be fired on process:

Event 'unhandledRejection':

Emitted whenever a possibly unhandled rejection is detected. This event is emitted with the following arguments:

reason the rejection reason of the promise susprected in having an unhandled rejection p the promise suspected in having an unhandled rejection itself.

process.on('unhandledRejection', function(reason, p){
    console.log("Possibly Unhandled Rejection at: Promise ", p, " reason: ", reason);
    // application specific logging here
});

For more info Unhandled Rejection

like image 29
zabusa Avatar answered Sep 27 '22 19:09

zabusa


Ok thanks to @pathurs and @Hendry I got what I needed.

First of all, the right way is what @Hendry suggested which was to not handle the catch in the wrapper, rather in the function call. This is the way I went:

function requestWrapper(url) {
    return request(url)
        .then(data => {...})
}
requestWrapper('http://some-url.com')
    .then(data => {...})
    .catch(err => console.log(err));

Great! But apparently, @pathurs way also works:

function requestWrapper(url) {
        return request(url)
            .then(data => {...})
            .catch(err => Promise.reject(err));
    }
    requestWrapper('http://some-url.com')
        .then(data => {...}, err => console.log(err));

I don't understand if that's a native feature, or some addition to request library: https://github.com/request/request-promise#thenonfulfilled-onrejected

like image 189
Moshe Avatar answered Sep 27 '22 19:09

Moshe