Помилки в async
Головне правило
Будь-яка
async-функція завжди повертає проміс. Якщо всередині неї викидається помилка (throw), то проміс переходить у станrejected.
Отже, помилки можна обробляти двома способами:
- через
try...catchусередині самої функції; - через
.catch()зовні при виклику.
1. Обробка через try...catch (усередині функції)
Це найзрозуміліший і найзвичніший спосіб - схожий на синхронний код.
async function getData() {
try {
const res = await fetch('https://api.github.com/404'); // помилка мережі
const data = await res.json();
console.log('Отримано:', data);
} catch (error) {
console.error('Помилка всередині async:', error.message);
}
}
getData();Вивід:
Помилка всередині async: Failed to fetchtry...catch "ловить":
- помилки, викинуті через
throw; - відхилені проміси, на яких стоїть
await.
Як це працює
await під капотом робить try { ... } catch { ... }
для промісу, який може завершитися з помилкою (reject).
const result = await Promise.reject('помилка');
// викине виняток → перейде в блок catch2. Обробка через .catch() (зовні функції)
Оскільки async-функція повертає Promise,
помилку можна обробити звичайним методом .catch():
async function getUser() {
const res = await fetch('https://wrong.url');
return res.json();
}
getUser()
.then(console.log)
.catch(err => console.error('Помилка зовні:', err.message));Вивід:
Помилка зовні: Failed to fetchВідмінність від try...catch:
тут помилка обробляється при виклику, а не всередині функції.
3. Приклад з ручним throw
async function example() {
const data = await Promise.resolve('OK');
if (!data) throw new Error('Немає даних!');
return data;
}
example()
.then(console.log)
.catch(err => console.error(err.message));Вивід:
OKЯкщо умова спрацює, throw перетвориться на Promise.reject().
4. Комбінація try...catch + повторний throw
Іноді потрібно обробити помилку частково, але передати її далі - наприклад, щоб залогувати.
async function processData() {
try {
const res = await fetch('https://wrong.url');
return await res.json();
} catch (err) {
console.error('Помилка запиту:', err.message);
throw new Error('Помилка при обробці даних');
}
}
processData().catch(err => console.error('Фінальна помилка:', err.message));Вивід:
Помилка запиту: Failed to fetch
Фінальна помилка: Помилка при обробці даних5. Обробка кількох помилок підряд
Можна використовувати кілька try...catch для різних етапів:
async function pipeline() {
try {
const res = await fetch('/api/data');
try {
const data = await res.json();
console.log('Дані:', data);
} catch (err) {
console.error('Помилка парсингу JSON:', err.message);
}
} catch (err) {
console.error('Помилка запиту:', err.message);
}
}Такий підхід корисний, коли потрібно обробити різні рівні помилок окремо.
6. Обробка без try...catch (через утиліту)
Іноді зручніше використовувати допоміжну функцію:
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('Помилка:', err.message);
console.log(data);
}Такий патерн часто використовують у Node.js, щоб не писати try...catch на кожному кроці.
7. Глобальне перехоплення необроблених помилок
Якщо забули .catch() або try...catch,
помилку можна перехопити глобально:
window.addEventListener('unhandledrejection', (event) => {
console.error('Необроблений проміс:', event.reason);
});Це аналог try...catch для всіх промісів, у яких немає .catch().
Проста аналогія
Уяви
async-функцію як квест.
await- це "завдання", яке може провалитися;try...catch- це "страховка": якщо провал - ти ловиш помилку і вирішуєш, що робити;.catch()зовні - це "гейм-майстер", який ловить фатальні помилки, якщо гравець не впорався.
ПІДСУМОК
| Спосіб | Де ловить помилку | Приклад |
|---|---|---|
try...catch | усередині async-функції | try { await ... } catch (e) { ... } |
.catch() | при виклику функції | myAsync().catch(e => ...) |
| Глобальне перехоплення | для всіх необроблених | window.addEventListener('unhandledrejection', ...) |
Патерн [err, data] | через обгортку | const [err, res] = await to(promise) |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.