133

Is there any difference between the 2 followings codes ?

myPromise.then(function() {
    console.log('success');
}).catch(function() {
    console.log('error');
});

myPromise.then(function() {
    console.log('success');
}, function() {
    console.log('error');
});

I know then and catch returns new promises resolved or rejected with the value returns in the callback. But i see the 2 codes around the web and i'm curious about the real differences between the 2 codes.

Magus
  • 14,796
  • 3
  • 36
  • 51
  • 4
    There is a very simple difference the fail will be called INSTEAD of the success function, the catch will be called AFTER the success function and it will also catch its errors – chrmcpn May 05 '17 at 19:59
  • 2
    @chrmcpn If the promise fails then it wouldn't call the success function right? So it wouldn't call if AFTER because it wouldn't call it at all given a failure in the promise itself? – user441521 May 21 '18 at 11:57
  • 11
    @user441521 Sorry I wasn't very clear. What I mean is that if there's an error IN the success callback the first code will catch it, but the second won't. In the case where the original promise fails there is no difference. – chrmcpn May 22 '18 at 18:51
  • catch will double as the second "then" function if one isn't offered, and it will do error catching for both in the case that both are used. then(success,fail).catch() would be the most robust. at least, this is my understanding so far – StayCool Aug 03 '20 at 16:11

1 Answers1

181

In your current code, they act the same because console.log('success'); will not fail.

However, if you write something like this...

myPromise.then(function() {
   // Some error may happen
   throw('An exception that would be caught');
}).catch(function() {
    console.log('error');
});
// Is the same as this, the errHandle tries to catch any unhandled error
// from previous result.
myPromise.then(func, null).then(null, errHandle);


myPromise.then(function() {
   // Some error may happen
   throw('An unhandled exception.');
}, function() {
    // This won't log the error if it happens in the 
    // some error may happen block.
    console.log('error');
});
// Is the same as this, the errHandle will handle errors from previous result,
// but it won't handle errs in func.
myPromise.then(func, errHandle)

The second form can't catch that error, while the first can.

Snippet for test:

// An function that may error and throw exception.
function funcThatThrows(test) {
  throw(`oops - error in test ${test}`);
}
function errHandler(exception) {
  console.log('We got an exception: ', exception);
}
// Expect: We got an exception:  oops - error in test 1
Promise.resolve(1).then(funcThatThrows).catch(errHandler);
// Is the same as below, the errHandler tries to catch any unhandled error
// from previous result.
// Expect: We got an exception:  oops - error in test 2
Promise.resolve(2).then(funcThatThrows, null).then(null, errHandler);

// If put the function and handler in the same then, the exception won't be caught.
// Expect: Uncaught (in promise) oops - error in test 3
Promise.resolve(3).then(funcThatThrows, errHandler);
fuyushimoya
  • 9,715
  • 3
  • 27
  • 34
  • 4
    so if i understand correctly if we don't use `.catch` we might miss errors thrown from the success handler. shoudln't we then **always** use the `.catch` instead of using the standard erroHandler function because `.catch` is doing exactly what the `errorHandler` function does only it does more and also catch errors from the success handler? – Jas Nov 03 '16 at 08:50
  • 2
    It depends, if you don't throw another exception in `.catch`, then the promise will resolve to what the function in `.catch` returns, and sometimes we want to handle exceptions in other place, e.g: `let promise2 = getAPromiseThatMayThrow();`, then you might not want to catch the exception from the returned promise but catch it at `promise2`, or you still want to catch it, log something, then throw it out, or you use specific return value to indicate `promise2`'s handler that prev step failed, it just depends. – fuyushimoya Nov 03 '16 at 09:06
  • 2
    if i do want my promise to handle errors and not propagate to other promises, in this case shouldn't i **always** use the `.catch` because it would do all that the error handling function does + also handle any exception thrown in the success? – Jas Nov 03 '16 at 12:00
  • 1
    I'll do so in that case. – fuyushimoya Nov 03 '16 at 12:44
  • I don't understand the answer at all. How are they different? – Matt Joiner Dec 18 '17 at 04:10
  • Exception in func in the first form will be caught and handled. But exception in func in the second form won’t be caught. – fuyushimoya Dec 18 '17 at 05:23
  • 19
    JavaScript, what are you?! – Paul T. Rawkeen Jan 22 '18 at 22:49
  • @fuyushimoya So if the promise itself was to give an error, it would call into the .catch() as well? I'm not talking the success callback in .then() throwing an error but the promise call itself throwing an error? So in a way having a .catch() can catch the promise itself failing or something inside the .then(success) function failing? – user441521 May 18 '18 at 14:54
  • @user441521 Yes, it'll catch any unhandled exception from previous chain. – fuyushimoya May 20 '18 at 15:20