3

How do we deal with errors that happen in the then function of a promise?

getLocationId(lat, lon, callback) { let self = this; return this._geocoder.reverse({lat: lat, lon: lon}) .then(this._parse) .catch(function(err) { callback(err); }); } _parse(res) { if (res.length < 1) throw new Error('No results from Maps API'); let value = res[0].administrativeLevels; if (!value || value.length < 1) { throw new Error('No administrative levels available'); } if ('level2long' in value) return value.level2long; if ('level1long' in value) return value.level1long; throw new Error('No suitable location found'); } 

For instance, how do I deal with this._parse throwing an error? I thought the catch function of the promise only deals with the reject handler. Does it also deal with errors thrown in the then?

2
  • 1
    O.T. but related: It is unnecessary to pass callback. Instead of getLocationId(lat, lon, errorHandler), exactly the same effect is achieved with getLocationId(lat, lon).catch(errorHandler). Commented Aug 1, 2016 at 8:33
  • This surprised me as well. I would want the .catch() (call it whatever you like) to only respond to Promise failure. Commented Oct 22, 2019 at 17:10

1 Answer 1

5

An exception thrown in any .then() handler will automatically be caught by the promise infrastructure and will turn the current promise chain into a rejected promise. The chain will then jump to the next .catch() handler where the exception will be the error reject reason.

Here's an example:

Promise.resolve().then(function() { throw "foo"; }).then(function() { console.log("in 2nd .then() handler"); // will not get here }).catch(function(err) { console.log(err); // will show "foo" }); 
Sign up to request clarification or add additional context in comments.

7 Comments

Great. Now what if you don't want this behavior? What if you want the error to somehow propagate outside of the Promise code? (But you still want to catch an error in the Promise itself.)
@Andrew - Well, you can't turn an asynchronous exception into a synchronous exception that's caught with a normal synchronous try/catch. So, it HAS to be handled via the promise infrastructure once it's inside a promise handler. You don't have to handle it locally. You can let it propagate up the promise chain and handle it in some level of caller above, but a .catch() or the equivalent when using async/await has to catch it somewhere.
@Andrew - Keep in mind an exception that occurs inside a .then() handler is asynchronous. Whatever synchronous code called this has ALREADY returned and is no longer active. So, that's why you can't catch it synchronously.
True. So if I don't control or don't know about potential errors, how would I be able to distinguish Promise errors vs. errors in the .then() code then?
@Andrew - You catch them the same place. They will just be different exceptions. No different than using try/catch with synchronous code where a coding error and a program condition that throws an exception both throw exceptions, just different exceptions.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.