Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Promise reject Possibly unhandled Error:

I have a function that does some operation using an array. I would like to reject it when the array is empty.

As an example

myArrayFunction(){
        return new Promise(function (resolve, reject) {
           var a = new Array();
           //some operation with a
           if(a.length > 0){
               resolve(a);
           }else{
               reject('Not found');
           }           
        };
}

When the reject operation happens I get the following error. Possibly unhandled Error: Not found

However I have the following catch when the call to myArrayFunction() is made.

handlers.getArray = function (request, reply) {
    myArrayFunction().then(
        function (a) {
            reply(a);
        }).catch(reply(hapi.error.notFound('No array')));
};

What would be the correct way to reject the promise, catch the rejection and respond to the client?

Thank you.

like image 517
Juan Avatar asked May 23 '14 21:05

Juan


People also ask

What is an unhandled promise rejection?

The Promise. reject() method returns a Promise object that is rejected with a given reason. The unhandledrejection event is sent to the global scope of a script when a JavaScript Promise that has no rejection handler is rejected; typically, this is the window, but may also be a Worker.

Why do I get an unhandled promise rejection with await promise all?

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 .

How do you handle rejection promises?

We must always add a catch() , otherwise promises will silently fail. In this case, if thePromise is rejected, the execution jumps directly to the catch() method. You can add the catch() method in the middle of two then() methods, but you will not be able to break the chain when something bad happens.


1 Answers

.catch takes a function as parameter however, you are passing it something else. When you don't pass a function to catch, it will silently just fail to do anything. Stupid but that's what ES6 promises do.

Because the .catch is not doing anything, the rejection becomes unhandled and is reported to you.


Fix is to pass a function to .catch:

handlers.getArray = function (request, reply) {
    myArrayFunction().then(function (a) {
        reply(a);
    }).catch(function(e) {
        reply(hapi.error.notFound('No array')));
    });
};

Because you are using a catch all, the error isn't necessarily a No array error. I suggest you do this instead:

function myArrayFunction() {
    // new Promise anti-pattern here but the answer is too long already...
    return new Promise(function (resolve, reject) {
            var a = new Array();
            //some operation with a
            if (a.length > 0) {
                resolve(a);
            } else {
                reject(hapi.error.notFound('No array'));
            }
        };
    }
}

function NotFoundError(e) {
    return e.statusCode === 404;
}

handlers.getArray = function (request, reply) {
    myArrayFunction().then(function (a) {
        reply(a);
    }).catch(NotFoundError, function(e) {
        reply(e);
    });
};

Which can be further shortened to:

handlers.getArray = function (request, reply) {
    myArrayFunction().then(reply).catch(NotFoundError, reply);
};

Also note the difference between:

// Calls the method catch, with the function reply as an argument
.catch(reply)

And

// Calls the function reply, then passes the result of calling reply
// to the method .catch, NOT what you wanted.
.catch(reply(...))
like image 121
Esailija Avatar answered Sep 18 '22 06:09

Esailija