Skip to content

Отчёты об ошибках

Адаптеры отчётности

Каждый адаптер — собственная точка входа exports, поэтому адаптер, который вы не импортируете, никогда не попадает в бандл.

ts
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/consolecreateConsoleReporter({ logger?, prefix? }), плюс готовый экземпляр consoleReporter. По умолчанию логирует через console.error; хороший вариант по умолчанию для разработки. Сообщения имеют префикс [vue-error-boundary-kit] — передайте prefix: '[my-app]', чтобы сменить бренд, или prefix: '', чтобы убрать его.
  • adapters/httpcreateHttpReporter({ endpoint, batchInterval?, maxBatchSize?, headers?, serialize? }). Отправляет POST через fetch (батчами, если batchInterval > 0); слушатель pagehide принудительно сбрасывает любой ожидающий батч через navigator.sendBeacon, поскольку выполняющийся fetch может быть прерван при фактическом закрытии страницы.
  • adapters/sentrycreateSentryReporter({ client, tags? }). @sentry/vue этим пакетом никогда не импортируется — передайте собственный уже инициализированный клиент Sentry (любой объект с методом captureException(error, hint?)); это остаётся тонкой, структурно типизированной обёрткой.
  • adapters/bugsnagcreateBugsnagReporter({ client, severity? }). Оборачивает Bugsnag.notify(error, onError), устанавливая event.context/event.severity и добавляя секцию метаданных errorBoundary через event.addMetadata(...). @bugsnag/js никогда не импортируется — передайте собственный инициализированный клиент.
  • adapters/logrocketcreateLogRocketReporter({ client, tags? }). Оборачивает LogRocket.captureException(error, { tags, extra }); поскольку LogRocket требует скалярных значений в extra, нескалярный контекст автоматически преобразуется через JSON.stringify. logrocket никогда не импортируется — передайте собственный инициализированный клиент.
  • adapters/otelcreateOtelReporter({ tracer, spanName?, attributes? }). Запускает span на каждую ошибку через собственный уже инициализированный OTel Tracer (например, 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/и т.д. почти идентичными отчётами:

ts
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().

ts
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 })
vue
<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').