- Home
- /
- Tutorials
- /
- JavaScript Tutorial
- /
- JavaScript Promise Errors
JavaScript Asynchronous
JavaScript Promise Errors
catchhandles a rejected promise, andfinallyruns whatever happened.
An error inside a promise does not crash the program; it rejects the promise.
If nothing catches it, the browser reports an unhandled rejection.
Example
Example
javascript
Promise.reject(new Error("no network"))
.catch(function (error) {
console.log("caught: " + error.message);
});The output is caught: no network.
Handling Failure
catch runs when the promise, or any step before it, fails.
finally runs either way and receives no value.
Throwing inside a then rejects the promise it returns.
Syntax
Syntax
javascript
promise
.then(handler)
.catch(handleError)
.finally(cleanUp);catch is shorthand for then(null, handler).
Throwing Inside a Handler
A thrown error becomes a rejection, so the catch picks it up.
Example
Example
javascript
Promise.resolve()
.then(function () {
throw new Error("something broke");
})
.catch(function (error) {
console.log(error.message);
});The output is something broke.
finally Always Runs
It is for cleanup, like hiding a loading spinner.
It does not change the value passing through.
Example
Example
javascript
Promise.reject("failed")
.catch(function (reason) {
console.log("handled " + reason);
})
.finally(function () {
console.log("cleaned up");
});The output is handled failed then cleaned up.
catch Placement Matters
A catch only covers the steps above it.
Putting it at the end is almost always what you want.
Example
Example
javascript
Promise.reject("early failure")
.catch(function (reason) {
return "recovered from " + reason;
})
.then(function (value) {
console.log(value);
});Because the catch came first, the then still runs.
Unhandled Rejections
A rejection with no catch is reported by the browser as an error.
Always end a chain with a catch.
Example
Example
javascript
Promise.reject("ignored")
.catch(function (reason) {
console.log("handled properly: " + reason);
});Removing the catch here would log an unhandled rejection warning.
Error Objects Carry More
Rejecting with an Error gives a message and a stack trace.
Example
Example
javascript
Promise.reject(new Error("bad id"))
.catch(function (error) {
console.log(error instanceof Error);
console.log(error.message);
});Rejecting with a plain string works but tells you less.
Complete Example
Complete Example
html
<!DOCTYPE html>
<html>
<head>
<title>JavaScript Promise Errors</title>
</head>
<body>
<h1>Promise Errors</h1>
<p id="out">Loading...</p>
<script>
function loadUser(id) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
if (id > 0) {
resolve("Ada");
} else {
reject(new Error("invalid id"));
}
}, 500);
});
}
loadUser(0)
.then(function (name) {
document.getElementById("out").textContent = "Welcome, " + name;
})
.catch(function (error) {
document.getElementById("out").textContent = "Failed: " + error.message;
})
.finally(function () {
console.log("request finished");
});
</script>
</body>
</html>Try It Yourself
Run the above example in the Try It Editor.
Try a valid id:
Change loadUser(0) to loadUser(1) and watch the other branch run.
Important Points
catchhandles a rejection from any earlier step.- Throwing inside a handler rejects the promise.
finallyruns either way and is for cleanup.- A
catchonly covers what comes before it. - Always end a chain with a
catch.
Conclusion
Promise error handling is one catch at the end of the chain.
Rejecting with an Error object gives you far more to work with.
An unhandled rejection is a bug, not a warning to ignore.
