Как обрабатывать ошибки в асинхронном коде
Короткий ответ
С await ошибки перехватывает обычный try...catch:
const loadUser = async () => {
throw new Error('User not found');
};
try {
await loadUser();
} catch (error) {
console.log('Error:', error.message);
}Результат:
Error: User not foundМетод catch
Без await добавьте к промису .catch():
const loadUser = async () => {
throw new Error('User not found');
};
await loadUser()
.then((user) => console.log(user))
.catch((error) => console.log('Error:', error.message));Результат:
Error: User not foundЗначение по умолчанию
.catch() может вернуть замену, и код пойдёт дальше:
const loadSettings = async () => {
throw new Error('offline');
};
const settings = await loadSettings().catch(() => ({ theme: 'light' }));
console.log(settings.theme);Результат:
lightfinally
finally выполняется в любом случае — удобно, чтобы спрятать индикатор загрузки:
let loading = true;
try {
await Promise.reject(new Error('failed'));
} catch (error) {
console.log(error.message);
} finally {
loading = false;
}
console.log('loading:', loading);Результат:
failed
loading: falseЧастая ошибка
try...catch вокруг промиса без await ничего не ловит: ошибка происходит позже, когда блок уже закончился:
const fail = async () => {
throw new Error('late error');
};
try {
fail().catch((error) => console.log('caught only by .catch():', error.message));
} catch {
console.log('never runs');
}Результат:
caught only by .catch(): late errorФункции из этого ответа
- try...catch — Перехватывает ошибки, чтобы программа не остановилась.
- Promise.allSettled — Ждёт завершения всех промисов и сообщает результат каждого — успех или ошибку.
- async function — Функция, которая всегда возвращает промис и внутри которой можно использовать await.