Отчёты об ошибках
Адаптеры отчётности
Каждый адаптер — собственная точка входа exports, поэтому адаптер, который вы не импортируете, никогда не попадает в бандл.
import { createConsoleReporter } from 'vue-error-boundary-kit/adapters/console'
import { createHttpReporter } from 'vue-error-boundary-kit/adapters/http'
import { createSentryReporter } from 'vue-error-boundary-kit/adapters/sentry'
import { createBugsnagReporter } from 'vue-error-boundary-kit/adapters/bugsnag'
import { createLogRocketReporter } from 'vue-error-boundary-kit/adapters/logrocket'
import { createOtelReporter } from 'vue-error-boundary-kit/adapters/otel'adapters/console—createConsoleReporter({ logger?, prefix? }), плюс готовый экземплярconsoleReporter. По умолчанию логирует черезconsole.error; хороший вариант по умолчанию для разработки. Сообщения имеют префикс[vue-error-boundary-kit]— передайтеprefix: '[my-app]', чтобы сменить бренд, илиprefix: '', чтобы убрать его.adapters/http—createHttpReporter({ endpoint, batchInterval?, maxBatchSize?, headers?, serialize? }). Отправляет POST черезfetch(батчами, еслиbatchInterval > 0); слушательpagehideпринудительно сбрасывает любой ожидающий батч черезnavigator.sendBeacon, поскольку выполняющийсяfetchможет быть прерван при фактическом закрытии страницы. Возвращаемый репортер также реализуетdestroy()— вызовите его, чтобы снять слушательpagehideи немедленно принудительно сбросить любой ожидающий батч (тот же путьsendBeacon/fetch); полезно при уничтожении того, что владеет репортером.adapters/sentry—createSentryReporter({ client, tags? }).@sentry/vueэтим пакетом никогда не импортируется — передайте собственный уже инициализированный клиент Sentry (любой объект с методомcaptureException(error, hint?)); это остаётся тонкой, структурно типизированной обёрткой.adapters/bugsnag—createBugsnagReporter({ client, severity? }). ОборачиваетBugsnag.notify(error, onError), устанавливаяevent.context/event.severityи добавляя секцию метаданныхerrorBoundaryчерезevent.addMetadata(...).@bugsnag/jsникогда не импортируется — передайте собственный инициализированный клиент.adapters/logrocket—createLogRocketReporter({ client, tags? }). ОборачиваетLogRocket.captureException(error, { tags, extra }); поскольку LogRocket требует скалярных значений вextra, нескалярный контекст автоматически преобразуется черезJSON.stringify.logrocketникогда не импортируется — передайте собственный инициализированный клиент.adapters/otel—createOtelReporter({ tracer, spanName?, attributes? }). Запускает span на каждую ошибку через собственный уже инициализированный OTelTracer(например,trace.getTracer('my-app')), вызываетrecordException()+setStatus({ code: ERROR }), добавляет поляCapturedErrorкак атрибуты span, затем завершает span.@opentelemetry/apiникогда не импортируется — передайте собственный tracer. Хотите привязать ошибки к текущему span вместо нового? Передайте{ startSpan: () => trace.getActiveSpan() ?? realTracer.startSpan(name) }в качествеtracer.
Все шесть адаптеров назначения принимают CapturedError и куда-то его пересылают; вы можете передать репортер (или массив) в любой <ErrorBoundary>, в useErrorBoundary() или в useGlobalErrorCapture().
Ограничение частоты и дедупликация
adapters/rate-limit оборачивает любой репортер(ы), чтобы защитить их от шторма массовых сбоев — например, сломанный список, перерисовывающийся сотни раз в секунду, который иначе завалит Sentry/HTTP/и т.д. почти идентичными отчётами:
import { createRateLimitedReporter } from 'vue-error-boundary-kit/adapters/rate-limit'
const reporter = createRateLimitedReporter([sentryReporter, consoleReporter], {
maxPerWindow: 10, // не более 10 отчётов пересылается за окно (по умолчанию: 10)
windowMs: 10_000, // размер окна (по умолчанию: 10 с)
dedupWindowMs: 10_000, // подавлять идентичные повторы в этом окне (по умолчанию: windowMs)
onSuppressed: (error, { reason, count }) => {
// reason: 'dedup' | 'rate-limit'
},
internalErrorPrefix: '[vue-error-boundary-kit]', // страховочный лог, если onSuppressed/обёрнутый репортер выбрасывает ошибку; '' чтобы убрать
})«Идентичность» означает совпадение source + componentName + message. Это сам по себе ErrorReporter, поэтому он комбинируется со всем остальным — передавайте его туда же, куда и любой другой репортер.
Хлебные крошки
adapters/breadcrumbs — скользящее окно «того, что произошло до ошибки», автоматически прикрепляемое к отчётам. Ничего не инструментируется автоматически: вызывайте addBreadcrumb() сами оттуда, где у вас уже есть информация (хук роутера, обработчик клика, экшен стейт-менеджмента) — тот же opt-in дух, что и у useGlobalErrorCapture().
import { createBreadcrumbTrail, withBreadcrumbs } from 'vue-error-boundary-kit/adapters/breadcrumbs'
const trail = createBreadcrumbTrail({ limit: 20 })
router.afterEach((to) => {
trail.addBreadcrumb({ category: 'navigation', message: `→ ${to.fullPath}` })
})
const reporter = withBreadcrumbs(sentryReporter, { trail })<ErrorBoundary :reporter="[reporter, trail.record]">…</ErrorBoundary>createBreadcrumbTrail({ limit? })—entries(в хронологическом порядке, от старых к новым — в отличие отcreateErrorHistory(), где сначала самые новые, что соответствует тому, как хлебные крошки читаются как таймлайн в других местах),addBreadcrumb({ category, message, timestamp?, data? }),clear()иrecord— сам по себеErrorReporter, поэтому передача его вместе с настоящим репортером(ами) автоматически добавляет каждую перехваченную ошибку и в трейл тоже, а значит, хлебные крошки последующей ошибки включают более ранние.withBreadcrumbs(reporter, { trail, contextKey?, internalErrorPrefix? })— оборачивает любой репортер(ы) так, чтобыcontextкаждого вызоваreport()включал текущие записи трейла под ключомcontextKey(по умолчанию:'breadcrumbs').