Обработка ошибок
Игнорирование конкретных ошибок
Не каждая выброшенная ошибка — баг, для которого стоит показывать fallback: классический случай — отменённый fetch, чей AbortError ожидаем и не должен трактоваться как падение компонента. И <ErrorBoundary>, и useGlobalErrorCapture() принимают для этого предикат shouldCatch: верните false, и ошибка пройдёт полностью нетронутой — без изменения состояния, без события error, без отчёта, без fallback.
<ErrorBoundary :should-catch="(e) => e.error?.name !== 'AbortError'">
<UserProfile :id="userId" />
</ErrorBoundary>Для <ErrorBoundary> отклонённый предикат — это не просто локальный no-op: ошибка продолжает распространяться через собственный механизм onErrorCaptured Vue, так что граница-предок (или обработчик ошибок уровня приложения) всё ещё получает шанс её увидеть, как будто этой границы вообще не было в дереве. Это отличается от всплытия с isolate: false, описанного ниже, — это собственный явный канал пакета для ошибок, которые он обработал локально.
useErrorBoundary() не принимает shouldCatch — поскольку captureError() вызывается явно из вашего собственного кода, вы уже сами контролируете, вызывать её или нет.
Вложенные границы
По умолчанию (isolate: true) ошибка полностью поглощается ближайшим <ErrorBoundary> — она не распространяется дальше, что соответствует собственной семантике onErrorCaptured во Vue для обработанной ошибки.
При isolate: false, обработав ошибку локально, граница также передаёт её ближайшему предку <ErrorBoundary> через внутренний канал provide/inject (а не через собственное всплытие onErrorCaptured во Vue, которое этот пакет намеренно блокирует на каждом уровне, чтобы иметь возможность отрисовать собственный fallback). Событие error предка срабатывает, его собственное состояние обновляется, и это становится видимым, если fallback предка заменит затронутый контент.
Репортер, подключённый к любой границе в цепочке, гарантированно вызывается ровно один раз на ошибку, даже если репортеры настроены и у дочерней границы, и у предка, — первая граница, которая фактически отправила отчёт, «забирает» его, и последующие границы в цепочке пропускают повторную отправку той же самой ошибки.
Что перехватывает и не перехватывает errorCaptured
onErrorCaptured во Vue (а значит, и <ErrorBoundary>) действительно перехватывает:
- Синхронные ошибки в функции рендера потомка или в
setup(). - Ошибки в
async setup()послеawait(с<Suspense>или без него). - Ошибки, выброшенные из скомпилированных Vue обработчиков
v-on— как@click="mayThrow"на нативных элементах, так и обработчики событий, генерируемых компонентами. - Колбэки watcher'ов, хуки директив, хуки переходов.
Он по-настоящему не перехватывает:
- Ошибки в сыром колбэке
addEventListener, минующем привязку событий Vue. - Ошибки в цепочках
setTimeout/Promise, не связанных с собственнымasync setup()компонента. - Необработанные отклонения промисов.
- Ошибки, выброшенные внутри вашего собственного обработчика
errorCapturedили репортера — этот пакет внутренне защищается от такой рекурсии (выбрасывающийonError/репортер перехватывается и логируется, никогда не повторно входя в состояние границы). - Повторную отправку отчёта об ошибке, уже обработанной дочерней границей с
isolate: false, — см. гарантию дедупликации выше.
Для первых трёх случаев используйте useErrorBoundary().captureError() или useGlobalErrorCapture().