Errors in async
The main rule
Any
asyncfunction always returns a promise. If it throws an error (throw) inside, the promise moves to therejectedstate.
So errors can be handled in two ways:
- via
try...catchinside the function itself; - via
.catch()outside, at the call site.
1. Handling via try...catch (inside the function)
This is the most readable and familiar way - it resembles synchronous code.
async function getData() {
try {
const res = await fetch('https://api.github.com/404'); // network error
const data = await res.json();
console.log('Received:', data);
} catch (error) {
console.error('Error inside async:', error.message);
}
}
getData();Output:
Error inside async: Failed to fetchtry...catch "catches":
- errors thrown via
throw; - rejected promises that have
awaiton them.
How it works
Under the hood, await does try { ... } catch { ... }
for a promise that can end up with an error (reject).
const result = await Promise.reject('error');
// throws an exception → goes to the catch block2. Handling via .catch() (outside the function)
Since an async function returns a Promise,
you can handle the error with the regular .catch() method:
async function getUser() {
const res = await fetch('https://wrong.url');
return res.json();
}
getUser()
.then(console.log)
.catch(err => console.error('Error outside:', err.message));Output:
Error outside: Failed to fetchThe difference from try...catch:
here the error is handled at the call site, not inside the function.
3. Example with a manual throw
async function example() {
const data = await Promise.resolve('OK');
if (!data) throw new Error('No data!');
return data;
}
example()
.then(console.log)
.catch(err => console.error(err.message));Output:
OKIf the condition triggers, throw turns into Promise.reject().
4. Combining try...catch with a re-throw
Sometimes you need to handle an error partially, but pass it further - for example, to log it.
async function processData() {
try {
const res = await fetch('https://wrong.url');
return await res.json();
} catch (err) {
console.error('Request error:', err.message);
throw new Error('Error while processing data');
}
}
processData().catch(err => console.error('Final error:', err.message));Output:
Request error: Failed to fetch
Final error: Error while processing data5. Handling several errors in a row
You can use several try...catch blocks for different stages:
async function pipeline() {
try {
const res = await fetch('/api/data');
try {
const data = await res.json();
console.log('Data:', data);
} catch (err) {
console.error('JSON parsing error:', err.message);
}
} catch (err) {
console.error('Request error:', err.message);
}
}This approach is useful when you need to handle different levels of errors separately.
6. Handling without try...catch (via a utility)
Sometimes it's more convenient to use a helper function:
const to = (promise) => promise.then(data => [null, data]).catch(err => [err]);
async function run() {
const [err, data] = await to(fetch('/api/user').then(r => r.json()));
if (err) return console.error('Error:', err.message);
console.log(data);
}This pattern is often used in Node.js, so you don't have to write try...catch at every step.
7. A global catch for unhandled errors
If you forget .catch() or try...catch,
you can catch the error globally:
window.addEventListener('unhandledrejection', (event) => {
console.error('Unhandled promise:', event.reason);
});This is the equivalent of try...catch for every promise that has no .catch().
A simple analogy
Think of an
asyncfunction as a quest.
awaitis a "task" that can fail;try...catchis "insurance": if it fails, you catch the error and decide what to do;.catch()outside is the "game master" who catches fatal errors if the player did not manage.
SUMMARY
| Way | Where it catches the error | Example |
|---|---|---|
try...catch | inside the async function | try { await ... } catch (e) { ... } |
.catch() | at the function call | myAsync().catch(e => ...) |
| Global catch | for all unhandled ones | window.addEventListener('unhandledrejection', ...) |
The [err, data] pattern | via a wrapper | const [err, res] = await to(promise) |
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.