Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як обробляти помилки в компонентах Vue: onErrorCaptured і app.config.errorHandler?

Помилка в рендері, хуку життєвого циклу, спостерігачі чи обробнику події одного компонента без обробки може зламати весь застосунок - користувач побачить «завмерлий» чи порожній екран.

Глобальний обробник - останній рубіж, місце для відправки в моніторинг:

const app = createApp(App);

app.config.errorHandler = (error, instance, info) => {
  // info - де сталася помилка: 'render function', 'mounted hook', 'watcher callback'...
  Sentry.captureException(error, { extra: { info } });
};

Він ловить помилки з рендеру, хуків, спостерігачів, обробників подій шаблону, setup, provide/inject - тобто з коду, який викликає Vue. Помилки з setTimeout, промісів без await і сторонніх колбеків він не бачить - для них window.onerror і unhandledrejection.

onErrorCaptured - перехоплення помилок нащадків у компоненті-предку. Основа для «межі помилок» (error boundary), як у React:

<!-- ErrorBoundary.vue -->
<script setup>
import { ref, onErrorCaptured } from 'vue';

const error = ref(null);

onErrorCaptured((err, instance, info) => {
  error.value = err;
  report(err, info);
  return false;   // не передавати помилку вище
});
</script>

<template>
  <div v-if="error" class="widget-error">
    Блок не завантажився. <button @click="error = null">Спробувати ще</button>
  </div>
  <slot v-else />
</template>
<ErrorBoundary>
  <RevenueChart />
</ErrorBoundary>

Зламаний графік показує запасний вигляд, решта дашборду працює.

Правила поширення:

  • помилка йде вгору ланцюжком батьків, викликаючи кожен onErrorCaptured;
  • return false зупиняє поширення - вище й до app.config.errorHandler вона не дійде;
  • якщо сам onErrorCaptured кидає помилку, вона теж іде до глобального обробника.

Пастки:

  • рендер запасного вигляду не повинен знову рендерити зламаний компонент - інакше нескінченний цикл помилок. Тому v-if/v-else, а не показ поверх;
  • асинхронні помилки в setup після await чи в звичайних промісах можуть не дійти до onErrorCaptured - async-код варто обробляти явно (try/catch);
  • app.config.warnHandler - окремо для попереджень (лише в режимі розробки).

Докладніше в документації: onErrorCaptured

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання