Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript Promise: Reject handler vs catch [duplicate]

I have come across multiple applications where using catch is preferred over rejectHandler. Eg: Preferring

new Promise.then(resolveHandler).catch()

instead of

new Promise().then(resolveHandler, rejectHandler).catch()

Is there a particular reason for this??

I find

new Promise().then(resolveHandler, rejectHandler).catch()

to be more useful because

  1. I can use rejectHandler to address designed/expected error scenario where Promise.reject is called.
  2. I can use catch block to address unknown/unexpected programming/runtime errors that occur.

Does someone know any particular reason why rejectHandler is not used much?

P.S. I am aware of newer alternatives in ES6 but I just curious to know this.

Update: I KNOW HOW rejectHandler and catch works. The question is why do I see more people use only catch over both rejectHandler and catch? Is this a best practice or there is some advantage?

Update(Adding answer here): Found the answer I was looking for first hand. The reason is not just because the error in reject is handled by catch it is mainly because of chaining. When we are chaining promise.then.then.then.then, having a resolve, reject pattern proves a bit tricky to chain it since you wouldn't want to implement a rejecthandler just to forward the rejectData up the chain. Using only promise/then/catch along with resolve/return/throw proves very useful in chaining N numbers of thenables. @Bob-Fanger(accepted answer) addressed some part of this too. Eg:

getData(id) {
        return service.getData().then(dataList => {
            const data = dataList.find(data => {
                return data.id === id;
            });
            if (!data) {
                // If I use Promise.reject here and use a reject handler in the parent then the parent might just be using the handler to route the error upwards in the chain
              //If I use Promise.reject here and parent doesn't use reject handler then it goes to catch which can be just achieved using throw.
                throw {
                    code: 404,
                    message: 'Data not present for this ID'
                };
            }
            return configuration;
        });
    }


//somewhere up the chain
....getConfiguration()
            .then(() => {
                //successful promise execution
            })
            .catch(err => {
                if (err.code) {
                    // checked exception
                    send(err);
                } else {
                    //unchecked exception
                    send({
                        code: 500,
                        message: `Internal Server error: ${err}`
                    });
                }
            });

Using just these All I need to worry about is promise/then/catch along with resolve/return/throw anywhere in the chain.

like image 281
wallop Avatar asked Aug 30 '26 23:08

wallop


2 Answers

Neither is more useful than the other. Both the rejected handler and the catch callback are called when an error is thrown or a promise is rejected.

There is no "best practice" to use one over the other. You may see code use one or the other, but it's use will be based on what the code needs to achieve. The programmer may want to catch an error at different times in the chain and handle errors thrown at different times differently.

Hopefully the following will help explain what I mean:

somePromise
  .then(
      function() { /* code when somePromise has resolved */ },
      function() { 
        /* code when somePromise has thrown or has been rejected. 
        An error thrown in the resolvedHandler 
        will NOT be handled by this callback */ }
   );

somePromise
  .then(
      function() { /* code when somePromise has resolved */ }
   )
   .catch(
      function() { 
        /* code when somePromise has thrown or has been rejected OR 
        when whatever has occurred in the .then 
        chained to somePromise has thrown or 
        the promise returned from it has been rejected */ }
   );

Notice that in the first snippet, if the resolved handler throws then there is no rejected handler (or catch callback) that can catch the error. An error thrown in a resolved callback will not be caught by the rejectedHandler that is specified as the second argument to the .then

like image 101
Adam Avatar answered Sep 01 '26 17:09

Adam


The difference is that if an error occurs inside resolveHandler it won't be handled by the rejectHandler, that one only handles rejections in the original promise.

The rejectHandler is not used in combination with catch that much, because most of the time we only care about that something went wrong.
Creating only one errorhandler makes the code easier to reason about.

If a specific promise in the chain should handled differently that can be a reason to use a rejectHandler, but i'd probably write a catch().then().catch() in that case.

like image 26
Bob Fanger Avatar answered Sep 01 '26 15:09

Bob Fanger



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!