- Home
- /
- Tutorials
- /
- JavaScript Tutorial
- /
- JavaScript async Error Handling
JavaScript Asynchronous
JavaScript async Error Handling
tryandcatchhandle errors in async functions the same way as anywhere else.
A rejected promise that is awaited throws.
That means ordinary try and catch work on asynchronous code.
Example
Example
javascript
async function run() {
try {
await Promise.reject(new Error("no network"));
} catch (error) {
console.log("caught: " + error.message);
}
}
run();The output is caught: no network.
Errors in async Functions
Awaiting a rejected promise throws the rejection reason.
try and catch around the await handle it.
An uncaught error inside an async function rejects the promise it returns.
Syntax
Syntax
javascript
try {
const value = await promise;
} catch (error) {
// handle it
}This is the same try and catch as anywhere else.
Wrapping Several Awaits
One try can cover a whole sequence of steps.
Example
Example
javascript
function step(n) {
return n === 2 ? Promise.reject(new Error("step two failed")) : Promise.resolve(n);
}
async function run() {
try {
await step(1);
await step(2);
console.log("never reached");
} catch (error) {
console.log(error.message);
}
}
run();The first failure jumps straight to the catch.
finally for Cleanup
It runs whether the work succeeded or failed.
Example
Example
javascript
async function run() {
try {
await Promise.reject(new Error("failed"));
} catch (error) {
console.log("handled");
} finally {
console.log("tidied up");
}
}
run();The output is handled then tidied up.
An Uncaught Error Rejects
An async function that throws returns a rejected promise.
The caller can catch it in the usual way.
Example
Example
javascript
async function run() {
throw new Error("inside");
}
run().catch(function (error) {
console.log("caught outside: " + error.message);
});The error escaped the function as a rejection.
Catching at the Call Site
Whether you handle it inside or outside is a design choice.
Example
Example
javascript
async function load() {
return await Promise.reject(new Error("gone"));
}
async function main() {
try {
await load();
} catch (error) {
console.log("main handled it: " + error.message);
}
}
main();Letting it bubble up keeps the lower function simpler.
Do Not Forget to Catch
Calling an async function without handling its rejection gives an unhandled rejection.
This is easy to miss because nothing looks wrong at the call site.
Example
Example
javascript
async function risky() {
throw new Error("boom");
}
risky().catch(function (error) {
console.log("handled: " + error.message);
});Writing just risky(); would leave the rejection unhandled.
Complete Example
Complete Example
html
<!DOCTYPE html>
<html>
<head>
<title>JavaScript async Error Handling</title>
</head>
<body>
<h1>async Error Handling</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);
});
}
async function show() {
const out = document.getElementById("out");
try {
const name = await loadUser(0);
out.textContent = "Welcome, " + name;
} catch (error) {
out.textContent = "Failed: " + error.message;
} finally {
console.log("finished");
}
}
show();
</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 see the success path.
Important Points
- Awaiting a rejected promise throws.
tryandcatchhandle it normally.- One
trycan cover several awaits. finallyruns either way.- An uncaught error rejects the promise the async function returns.
Conclusion
Error handling in async code uses the same tools as everywhere else.
That is a large part of why async and await are easier to read.
The rule stays the same: every asynchronous call needs somewhere for failure to go.
