Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I assume that error in a promise will bubble to new Promise and catch that?

I have a function which is going to look up the cache if it finds anything, otherwise then then it will go ahead and fetch the data and set the cache. It's pretty standard. I'm wondering if the error occurs at the most inner function, will it keep bubble up to the outer most Promise? So, I can just have one catch instead of one.

Here's my code.

I'm using Bluebird

 var _self = this;
    return new Promise(function(resolve, reject) {
      _self.get(url, redisClient).then(function getCacheFunc(cacheResponse) {
        if(cacheResponse) {
          return resolve(JSON.parse(cacheResponse));
        }
        webCrawl(url).then(function webCrawl(crawlResults) {
          _self.set(url, JSON.stringify(crawlResults), redisClient);
          return resolve(crawlResults);
        }).catch(function catchFunc(error) {
          return reject(error); // can I delete this catch
        });
      }).catch(function getCacheErrorFunc(cacheError) {
        return reject(cacheError); // and let this catch handle everything?
      });
    });
like image 694
toy Avatar asked Feb 11 '16 17:02

toy


People also ask

How do you catch an error on a promise?

Inside the promise, the catch() method will catch the error caused by the throw statement and reject() . If an error occurs and you don't have the catch() method, the JavaScript engine issues a runtime error and stops the program.

What happens if one of the promises in promise race rejects with an error?

The promise2 is rejected with error at t1 . Because the promise2 is resolved earlier than the promise1 , the promise2 wins the race. Therefore, the Promise. race([promise1, promise2]) returns a new promise that is rejected with the error at t1 .

Can you use try catch in promise?

You cannot use try-catch statements to handle exceptions thrown asynchronously, as the function has "returned" before any exception is thrown. You should instead use the promise. then and promise. catch methods, which represent the asynchronous equivalent of the try-catch statement.

Can we add then after catch in promise?

The catch method is used for error handling in promise composition. Since it returns a Promise , it can be chained in the same way as its sister method, then() . catch() internally calls then() .


2 Answers

Yes, it is possible to have a single .catch(...) for deeply-nested Promises. The trick: you can resolve a Promise with another Promise. This means that you can refactor your code to:

var _self = this;
_self.get(url, redisClient)
  .then(function(cacheResponse) {
    if(cacheResponse) {
      // Resolve the Promise with a value
      return JSON.parse(cacheResponse);
    }

    // Resolve the Promise with a Promise
    return webCrawl(url)
      .then(function(crawlResults) {
        _self.set(url, JSON.stringify(crawlResults), redisClient);

        // Resolve the Promise with a value
        return crawlResults;
      });
  })
  .catch(function(err) {
    console.log("Caught error: " + err);
  });

Note: I also removed your outermost Promise declaration. This was no longer necessary since _self.get(...) already returned a Promise.

like image 65
Brian Lauber Avatar answered Sep 30 '22 01:09

Brian Lauber


Assuming that .get returns a Promise you would write it that way:

 var _self = this;
 return _self.get(url, redisClient).then(function(cacheResponse) {
   if (cacheResponse) {
     return JSON.parse(cacheResponse);
   } else {
     return webCrawl(url).then(function(crawlResults) {
       _self.set(url, JSON.stringify(crawlResults), redisClient);
       return crawlResults;
     })
   }
 });

There is no need to introduce a new Promise because you already get one from your _self.get

like image 34
t.niese Avatar answered Sep 30 '22 03:09

t.niese