3

Following is an example:

var promise = new Promise(function(resolve, reject) {
  throw new Error('test');
});
promise.catch(function(error) {
  console.log(error + ' 1 ');
  return error
}).catch(function(error) {
  console.log(error + ' 2 ');
  return error
})

The result for the codes are:

Error: test 1 

As can be seen, the second catch call doesn't work. Does that mean Promise cannot handle error using the chain syntax of catch? Is there a way to pass the current error to the next catch() call?

Hanfei Sun
  • 45,281
  • 39
  • 129
  • 237
  • 3
    You never rethrow the error. Why would a return value be considered an error to be caught? Use `throw error;` instead, and you should get the behaviour you expect. – Luaan Apr 05 '16 at 08:22
  • Possible duplicate of http://stackoverflow.com/questions/35042068/why-is-onrejected-not-called-following-promise-all-where-promise-reject-incl – guest271314 Apr 05 '16 at 08:25
  • If you *return* something from `catch`, you're saying you've handled the problem and this is the value to continue with. If you haven't handled the problem, *rethrow* rather than returning. – T.J. Crowder Apr 05 '16 at 08:25
  • 1
    It's basically like asking why `try { try { throw new Error } catch (e) { log(e); return e } } catch (e) { log(e); return e }` doesn't log twice. Because you already caught the error. – idbehold Apr 05 '16 at 18:12

2 Answers2

7

Returning the error will not make it hit the next catch. You need to throw the error again:

promise.catch(function(error) {
  console.log(error + ' 1 ');
  throw error
}).catch(function(error) {
  console.log(error + ' 2 ');
  return error
})
-> Error: test 1 
-> Error: test 2 
James Donnelly
  • 126,410
  • 34
  • 208
  • 218
3

You have to throw the error again, as opposed to just returning an error object:

var promise = new Promise(function(resolve, reject) {
  throw new Error('test');
});
promise.catch(function(error) {
  console.log(error + ' 1 ');
  throw error
}).catch(function(error) {
  console.log(error + ' 2 ');
  return error
})

js has no internal notion of "this is an error object so throw it" - if there had been a then() clause following your first catch(), operation would have been deferred to that, like so:

var promise = new Promise(function(resolve, reject) {
  throw new Error('test');
});
promise.catch(function(error) {
  console.log(error + ' 1 ');
  return error
}).then(function(error) {
  console.log(error + ' 2 ');
  return error
})

Hope this helps!

jonny
  • 3,022
  • 1
  • 17
  • 30
  • I wonder what "this is an error object so throw` feature would look like or even what it would mean. –  Apr 05 '16 at 08:25
  • @T.J.Crowder I edited my wording so I'm gunna delete all my comments to clean up the answer :) – jonny Apr 05 '16 at 08:31