В современном вебе надёжная обработка ошибок критична для UX и бизнес‑аналитики. Если вы используете Vue 3 и Pinia, то можно создать глобальный error handler, который автоматически перехватывает любые исключения, сохраняет их в Pinia и отправляет в Sentry для дальнейшего анализа. Это решение обеспечивает единый поток ошибок, упрощает отладку и повышает надёжность приложения. В этой статье мы разберём, как реализовать такой механизм, шаг за шагом.
Разбор задачи
В Vue 3 ошибки могут возникнуть в шаблонах, хуках, методах компонентов, а также в асинхронных задачах. Если не обрабатывать их централизованно, то пользователь видит непонятные сообщения, а разработчик теряет контекст. Pinia удобно использовать как хранилище для ошибок, позволяя легко отобразить их в UI или экспортировать. Sentry, в свою очередь, обеспечивает мощный бекенд для агрегации, алёртов и трассировки. Комбинируя эти инструменты, мы получаем полноценную систему мониторинга.
Пошаговое решение
1. Создаём глобальный error handler в main.js, используя app.config.errorHandler. 2. Внутри обработчика сохраняем ошибку в Pinia store, добавляя поля: сообщение, стэк, метаданные и timestamp. 3. Далее, если Sentry подключён, отправляем событие через sentry.captureException. 4. Для отладки можно вывести ошибку в консоль и добавить пользовательский UI‑компонент, который читает store и показывает список ошибок в таблице. 5. Не забудьте настроить фильтрацию, чтобы не дублировать ошибки и не отправлять уже игнорируемые события. 6. Тестируем: генерируем ошибки в разных местах и проверяем, что они попадают в Pinia и Sentry. Это простая, но надёжная интеграция, которую можно масштабировать, добавляя роли пользователей, уровни логирования и периодическую очистку старых записей.
Рабочий код
import { createApp } from 'vue'
import { createPinia, defineStore } from 'pinia'
import * as Sentry from '@sentry/vue'
import { Integrations } from '@sentry/tracing'
// 1️⃣ Инициализируем Pinia
const pinia = createPinia()
// 2️⃣ Создаём store с глобальным обработчиком ошибок
const useErrorStore = defineStore('error', {
state: () => ({ errors: [] }),
actions: {
addError(err) {
this.errors.push(err)
// Отправляем в Sentry
Sentry.captureException(err)
}
}
})
// 3️⃣ Настраиваем глобальный обработчик ошибок Vue
const app = createApp(App)
app.use(pinia)
app.use(Sentry, {
dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0',
integrations: [new Integrations.BrowserTracing()],
tracesSampleRate: 1.0,
beforeSend(event, hint) {
// Пример фильтрации незначительных ошибок
if (hint.originalException?.message?.includes('Ignored')) {
return null
}
return event
}
})
app.config.errorHandler = (err, instance, info) => {
const errorStore = useErrorStore()
errorStore.addError({ message: err.message, info, instance })
}
app.mount('#app')
Типичные ошибки
- Не подключён Pinia до создания store – приводит к ошибке «pinia is not installed».
- Синтаксическая ошибка в beforeSend: возвращён null без проверки, может блокировать отправку.
- Отсутствует обработка асинхронных ошибок из промисов – они попадают в глобальный handler только при .catch.
FAQ
В чем разница между app.config.errorHandler и Vue.config.errorHandler?
app.config.errorHandler применяет только к текущему приложению, Vue.config.errorHandler глобален для всех инстанций Vue.
Можно ли отключить Sentry для определённого store?
Да, просто не вызывать Sentry.captureException в нужных действиях или использовать условие внутри addError.
Как отлавливать ошибки из async/await?
Оберните async функции в try/catch и передавайте err в global handler либо в store. Vue 3 автоматически ловит ошибки из render‑функций, но async/await нужно обрабатывать вручную.
Заключение и чек‑лист
- Pinia подключена до создания store.
- Глобальный errorHandler определён после use(Sentry).
- Sentry настроен с DSN и beforeSend.
- Store содержит метод addError, который записывает и отправляет в Sentry.
- Проверены типичные ошибки: синтаксис, async‑помехи, фильтрация.
