Обработка ошибок: errorCaptured, app.config.errorHandler

↑ 4.1 Vue 3: основы, компоненты, Composition API · ← Предыдущая · → Следующая

Обязательно~3 мин чтенияУровень: middle

Зачем это на собесе

Как не уронить приложение из-за ошибки в одном компоненте и собрать данные об ошибках.

Объяснение

Уровни обработки:

УровеньМеханизм
Локальныйtry/catch в обработчиках и async-функциях
Компонентная границаonErrorCaptured (ловит ошибки потомков: рендер, хуки, watchers, обработчики)
Глобальныйapp.config.errorHandler
Предупрежденияapp.config.warnHandler (dev)
Вне Vuewindow.addEventListener("error" / "unhandledrejection")
Роутерrouter.onError
Запросыобработка в API-клиенте/интерсепторах, onError в Vue Query
<!-- ErrorBoundary.vue -->
<script setup lang="ts">
const error = ref<Error | null>(null);
onErrorCaptured((err, instance, info) => {
  error.value = err as Error;
  report(err, { info, component: instance?.$options.name });
  return false;                              // остановить дальнейшее всплытие
});
const reset = () => (error.value = null);
</script>
<template>
  <slot v-if="!error" />
  <div v-else role="alert"><p>Что-то пошло не так</p><button @click="reset">Повторить</button></div>
</template>
// main.ts
app.config.errorHandler = (err, instance, info) => { Sentry.captureException(err, { extra: { info } }); };
window.addEventListener("unhandledrejection", (e) => Sentry.captureException(e.reason));

Практики:

  • Error boundary вокруг крупных блоков (страница, виджет), чтобы сбой не «ронял» всё приложение.
  • Понятные сообщения пользователю и кнопка «Повторить»; технические детали — в логи.
  • Логирование в Sentry/аналог с контекстом (пользователь, маршрут, версия, breadcrumbs), source maps.
  • Разделять ошибки: ожидаемые (валидация, 4xx) обрабатывать локально, неожиданные — глобально.
  • Асинхронные ошибки в обработчиках событий Vue перехватываются глобальным обработчиком; вне Vue — нет.

Нюансы и подводные камни

  • errorCaptured не ловит ошибки в самом компоненте-границе и в асинхронном коде вне Vue.
  • Возврат false в errorCaptured останавливает распространение.
  • unhandledrejection для промисов вне компонентов.
  • Не глотайте ошибки: минимум — логирование.

Практика

  1. Сделайте ErrorBoundary и оберните им страницы.
  2. Настройте отправку ошибок в Sentry с source maps.
  3. Смоделируйте ошибку рендера и проверьте поведение.

Вопросы с ответами

Связанные темы