Ответ вслух Middle Промисы и async/await обновлено

Обработка ошибок в асинхронном коде

Вопрос

Как вы обрабатываете ошибки в асинхронном коде? Где ошибки чаще всего теряются?

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Образцовый ответ: «В async-функциях оборачиваю await в try/catch, в цепочках ставлю catch в конце. Важно решить, где ошибку обрабатывать: на нижнем уровне я обычно добавляю контекст и пробрасываю дальше через new Error('...', { cause: err }), а показываю пользователю на верхнем.

Что должно прозвучать в ответе

  • `try/catch` вокруг `await` или `catch` в конце цепочки

  • Потеря при забытом `return` или `await`: промис не попадает в цепочку

  • `return` без `await` внутри `try` не ловит отклонение

  • Исключения в колбэках таймеров и событий внутри executor не превращаются в reject

  • Глобальные сети: `unhandledrejection` в браузере, `process.on('unhandledRejection')` в Node, Node 15+ падает

  • `allSettled` для частичных отказов, `Error.cause` для обёртки ошибок

Что могут спросить следом

  • Чем return await отличается от return в async-функции?
  • Как показать пользователю результат, если из трёх запросов упал один?
  • Как добавить контекст к ошибке, не потеряв исходную?

Разбор

Образцовый ответ: «В async-функциях оборачиваю await в try/catch, в цепочках ставлю catch в конце. Важно решить, где ошибку обрабатывать: на нижнем уровне я обычно добавляю контекст и пробрасываю дальше через new Error('...', { cause: err }), а показываю пользователю на верхнем. Теряются ошибки в типичных местах. Забыли return в then или await перед вызовом: промис живёт сам по себе, и его отклонение не попадёт ни в какой catch. return promise внутри try без await: блок уже завершился, когда промис отклонится. Исключение внутри колбэка таймера в executor промиса: промис его не видит. Для страховки есть глобальные обработчики, unhandledrejection в браузере и process.on('unhandledRejection') в Node; в Node с 15 версии такой промис роняет процесс, это лучше, чем молчание. Если операции независимы и частичный отказ допустим, использую allSettled и показываю то, что загрузилось».

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме