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
}
);