Exceptions in promise chain in JavaScript

Suppose for some reason our promise will end with an error:

let promise = new Promise(function(resolve, reject) { setTimeout(function() { reject('error'); }, 3000); });

In this case, the execution of the code will immediately jump to then, which has an error handler function, or to the first catch, whichever comes first.

Here is an example of the first situation:

promise.then( function(result) { return result + '1'; } ).then( function(result) { return result + '2'; }, function(error) { // an execution jumps to here } ).then( function(result) { console.log(result); } );

Here is an example of the second situation:

promise.then( function(result) { return result + '1'; } ).then( function(result) { return result + '2'; } ).catch( function(error) { // an execution jumps to here } ).then( function(result) { console.log(result); } );

The handler function has two options: if it handled the exception, it can return a result via return and execution will continue further down the chain. If it didn't cope with the error, then it can either return nothing, or throw an exception via throw. In this case, execution will jump to the next error hook (at then or catch, whichever comes first).

As a rule, all chain errors are caught in one place: catch is placed at the end of the chain:

promise.then( function(result) { return result + '1'; } ).then( function(result) { return result + '2'; } ).catch( function(error) { // we get here in case of an error } );

In this case, an exception can occur in the promise itself, or thrown via throw in any link in the chain:

promise.then( function(result) { return result + '1'; } ).then( function(result) { if (everythingIsFine) { return result + '2'; } else { throw new Error('an error'); // we go to the nearest interceptor } } ) .then( function(result) { return result + '3'; } ).catch( function(error) { // the nearest interceptor } );

Keep in mind that catch is needed specifically for diagnosing an error: is it solvable or not. If the error is solvable, then catch must pass its solution to the next then. And if it isn't solvable (or the given catch simply doesn't know how to resolve it), then we must either return nothing or throw an exception:

promise.then( function(result) { return result + '1'; } ).then( function(result) { return result + '2'; } ).catch( function(error) { if (errorIsSolvable) { return 'data'; // we send it to the next then } else { // we return nothing or throw an exception } } ).then( function(result) { // we solve an error here } );
enru