Интеграции с фреймворками
Интеграция с Nuxt
Nuxt поставляет собственный <NuxtErrorBoundary> (обёртку над onErrorCaptured) и страницу error.vue для ошибок всего приложения. Этот пакет дополняет их, а не заменяет:
<NuxtErrorBoundary>— тонкая, узкоспециализированная обёртка со слотом#errorи без собственной истории повторов/сбросов/отчётности — используйте<ErrorBoundary>из этого пакета, когда нужныresetKeys,maxRetries, счётчики попыток или репортер на уровне компонента.error.vueобрабатывает ошибки, дошедшие до корня приложения (включая те, которые компонентная граница решила не изолировать, или произошедшие до монтирования любой границы). Держите её как последний рубеж защиты; используйте<ErrorBoundary>для частей дерева, которые должны деградировать изящно, а не обрушивать всю страницу.- Оба механизма опираются на один и тот же
onErrorCaptured, так что в обоих случаях применим один и тот же список того, что перехватывается и не перехватывается.
Модуль vue-error-boundary-kit/nuxt
Добавьте его в nuxt.config.ts для автоматической регистрации — никаких ручных импортов в коде приложения не нужно:
export default defineNuxtConfig({
modules: ['vue-error-boundary-kit/nuxt'],
})Это регистрирует <ErrorBoundary> как глобальный компонент и автоимпортирует useErrorBoundary, useGlobalErrorCapture и useNuxtErrorBoundary (ниже) — проверено end-to-end на реальном приложении Nuxt 4.5.2, собранном из опубликованного tarball пакета, включая то, что типизация опций модуля в nuxt.config.ts действительно ловит опцию неправильной формы.
Опции модуля (все опциональны, обе по умолчанию true):
export default defineNuxtConfig({
modules: ['vue-error-boundary-kit/nuxt'],
errorBoundaryKit: {
component: true, // зарегистрировать <ErrorBoundary> глобально
autoImports: true, // автоимпортировать три composable выше
},
})@nuxt/kit — лишь peer-зависимость этого пакета (peerDependenciesMeta.optional), никогда не бандлится в ваше приложение — она уже входит в любую установку Nuxt, поэтому добавлять нечего. Протестировано на Nuxt 4.5.2; заявленная compatibility: { nuxt: '>=3.0.0' } у модуля выведена из собственного кросс-мажорного (2/3/4) дизайна @nuxt/kit, а не проверена независимо на Nuxt 3.
useNuxtErrorBoundary()
useErrorBoundary() плюс подключённые собственные хуки Nuxt vue:error и app:error — то есть также перехватывает то, что ускользает из любого <ErrorBoundary> в вашем дереве (ошибку рендера/setup, дошедшую до корня приложения необработанной), а также собственный фатальный поток showError()/createError() в Nuxt, который граница на уровне компонента вообще не видит. Оба хука работают изоморфно, так что это покрывает и SSR, и клиент. Обычно вызывается один раз, например, в app.vue:
<!-- app.vue -->
<script setup lang="ts">
const { error } = useNuxtErrorBoundary({ reporter: sentryReporter })
</script>
<template>
<ErrorBoundary :reporter="sentryReporter">
<NuxtPage />
</ErrorBoundary>
</template>Для ошибок, которые вы хотите отдать на обработку собственной error.vue фреймворка (например, 404 из createError()), не оборачивайте их в локальную границу — дайте им распространиться дальше.
Интеграция с vue-router
vue-error-boundary-kit/router — useRouterErrorBoundary(), эквивалент useNuxtErrorBoundary(), но только для vue-router. router.onError() — собственный catch-all vue-router: он срабатывает для ошибок, выброшенных в navigation guards, ошибок, переданных в next(), и ошибок, возникших при разрешении асинхронного компонента маршрута (component: () => import(...)), — ничто из этого не происходит внутри render/setup жизненного цикла компонента, поэтому onErrorCaptured/<ErrorBoundary> структурно никогда этого не видят.
import { useRouterErrorBoundary } from 'vue-error-boundary-kit/router'<!-- App.vue -->
<script setup lang="ts">
const { error } = useRouterErrorBoundary({ reporter: sentryReporter })
</script>Те же опции, что у useErrorBoundary() (onError, beforeReset, reporter, reportContext, internalErrorPrefix); автоматически отписывается от router.onError() при уничтожении effect scope. vue-router — опциональная peer-зависимость, никогда не бандлится, если вы не импортируете эту точку входа. Проверено на реальном router.onError() — подтверждено, что до него действительно доходят и выбрасывающий navigation guard, и отклонённый асинхронный компонент маршрута, против vue-router@5.2.0; заявленный диапазон peerDependencies (^4.0.0 || ^5.0.0) выведен из стабильной, давно устоявшейся сигнатуры onError, а не проверен независимо на 4.x.
Интеграция с TanStack Query
retry()/reset() у <ErrorBoundary> только перерисовывают дерево. useQuery(), уже завершившемуся ошибкой, до этого нет дела — он остаётся в своём закэшированном состоянии ошибки и, при установленном throwOnError, при самом следующем рендере повторно выбрасывает ту же устаревшую ошибку, прежде чем его функция запроса вообще запустится заново. @tanstack/react-query решает это через QueryErrorResetBoundary; у @tanstack/vue-query нет эквивалентного примитива, поэтому его предоставляет vue-error-boundary-kit/tanstack-query:
import { useQueryErrorReset } from 'vue-error-boundary-kit/tanstack-query'<script setup lang="ts">
const resetErroredQueries = useQueryErrorReset()
</script>
<template>
<ErrorBoundary :before-reset="resetErroredQueries">
<template #default>
<UserProfile :id="userId" />
<!-- использует useQuery({ ..., throwOnError: true }) -->
</template>
<template #fallback="{ error, retry }">
<ErrorState :message="error.message" @retry="retry" />
</template>
</ErrorBoundary>
</template>useQueryErrorReset(options?) возвращает синхронный колбэк, сбрасывающий все запросы, находящиеся в состоянии ошибки (queryClient.resetQueries({ predicate: (query) => query.state.status === 'error' })), — подключите его к beforeReset, чтобы он запускался непосредственно перед собственным повторным рендером границы, и повторённый запрос действительно рефетчился, а не мгновенно проваливался снова. Опции: queryClient (по умолчанию: useQueryClient() из контекста), id (передаётся в useQueryClient() для мультиклиентских настроек), internalErrorPrefix. @tanstack/vue-query — опциональная peer-зависимость, никогда не импортируется, если вы не импортируете эту точку входа.