The Promise catch()
Function in JavaScript (original) (raw)
Mar 25, 2020
Promises in JavaScript are an object representation of an asynchronous operation. Promises are like a placeholder for some value that may not have been computed yet. If the async operation failed, JavaScript will reject the promise. The catch()
function tells JavaScript what function to call if the promise is rejected:
const p = Promise.reject(new Error('Oops!'));
p.catch(err => {
err.message; // 'Oops!'
});
With Promise Chaining
The major benefit of .catch()
is that you can catch errors that occurred anywhere in a promise chain.
const p = Promise.resolve('Na');
return p.
then(str => str + ' Na').
then(str => str + ' Na').
then(str => str + ' Na').
then(() => { throw new Error('Batman!') }).
then(() => console.log('Will not print')).
catch(err => {
err.message; // 'Batman!'
});
This means you only need one catch()
at the end of a promise chain to handle any errors that occur in the promise chain!
Rethrow Errors
You can rethrow errors in .catch()
, similar to rethrowing with try/catch.
const p = Promise.reject(new Error('Oops!'));
return p.
catch(err => { throw err; }). // Rethrow the error
catch(err => {
err.message; // 'Oops!'
});
This also means you should be very careful about uncaught errors in your.catch()
error handlers. If the function you pass to .catch()
throws and you don't have another .catch()
afterward, you'll get an unhandled promise rejection.
Unwrapping Errors
If your .catch()
returns a value, you can "unwrap" that value withawait
or then()
.
const p = Promise.reject(new Error('Oops!'));
const answer = await p.catch(() => 42);
answer; // 42
return p.
catch(() => 42).
then(answer => {
answer; // 42
});
In other words, you can handle async errors in JavaScript using Golang-like syntax.
const p = Promise.reject(new Error('Oops!'));
const err = await p.catch(err => err);
err.message; // 'Oops!'
Versus then()
The catch()
function is just a thin layer of syntactic sugar on top of the Promise then() function. Recall that then()
takes 2 parameters:
onFulfilled()
: JavaScript will call this function if the underlying async operation succeeded.onRejected()
: JavaScript will call this function if the underlying async operation failed.
So .catch(fn)
is the same thing as .then(null, fn)
. In other words, below is a one-line polyfill for catch()
:
Promise.prototype.catch = function(onRejected) {
return this.then(null, onRejected);
};
That means you can handle promise errors with .then()
as well:
const p = Promise.reject(new Error('Oops!'));
return p.then(() => {}, function onRejected(err) {
err.message; // 'Oops!'
});