Перейти к содержимому

Теги и контекст ​

И то, и другое прикрепляется к каждому событию, пойманному после установки, но задачи у них разные:

  • Теги (setTag(key, value)) — плоские пары key: string, значение всегда приводится к строке. По ним в первую очередь ищет строка поиска панели в фильтре key:value, например checkout.step:payment прямо в поиске Исключений/Трейсов/Логов (см. Поиск).
  • Контекст (setContext(key, value)) прикрепляет вложенный объект под пространством имён (setContext('order', { id, total }) становится order.id / order.total в событии). Он для описательных данных, которые нужно видеть на странице события, и тоже участвует в поиске, если тега с тем же ключом нет.

Оба необязательны — для перехвата ошибки ничего из этого не нужно. Короткая версия — на странице Пользователи и контекст.

Задание тегов и контекста ​

ts
Buglapse.setTag('checkout.step', 'payment')
Buglapse.setTag('plan', 'pro')

Buglapse.setContext('order', { id: order.id, total: order.total, currency: 'USD' })

После установки значение тега/контекста прикрепляется к каждому событию, пойманному дальше, — исключениям, логам, трейсам, спанам, — пока вы снова не вызовете setTag/setContext с тем же ключом. unset нет; перезапишите ключ новым значением.

setContext разворачивает вложенные объекты в ключи через точку под заданным префиксом, так что setContext('order', { customer: { id: 42 } }) даёт order.customer.id — так же разворачиваются контексты device.*/browser.* (см. Настройка). Массивы и простые значения внутри объекта сохраняются как есть под своим развёрнутым ключом.

Пользователи ​

setUser() — тонкая обёртка над setContext('user', ...), которая к тому же определяет, к какому пользователю относится событие, — карточка пользователя в событии, затронутые пользователи инцидента, фильтр поиска user::

ts
Buglapse.setUser({ id: user.id, email: user.email, username: user.username })

Все поля необязательны, и повторный вызов дополняет уже известное, а не заменяет: вызовите один раз с одним id при входе, потом снова с email, когда он появится, — сохранится и то, и другое. Любые поля помимо id/email/username/name тоже сохраняются, просто не участвуют в порядке сопоставления id → email → IP, по которому панель различает пользователей проекта (без setUser используется IP запроса).

Временное наложение через withScope() ​

setTag/setContext меняют то, что прикрепляется глобально, с этого момента. withScope() вместо этого накладывает теги/контекст на один колбэк, не трогая заданное глобально:

ts
Buglapse.withScope((scope) => {
    scope.setTag('checkout.step', 'payment')
    scope.setContext('order', { id: order.id, total: order.total })

    try {
        chargeCard(order)
    } catch (error) {
        Buglapse.captureException(error)
    }
})

Любое событие, пойманное внутри колбэка, несёт наложение поверх глобальных тегов/контекста; всё, что поймано после возврата из withScope(), его не видит. scope.setUser() делает то же для пользователя — это областная версия setUser().

Наложение живёт только в синхронной части колбэка. У браузерного клиента нет AsyncLocalStorage, чтобы перенести его через await, поэтому:

ts
// ❌ теряет наложение — перехват после await
Buglapse.withScope(async (scope) => {
    scope.setTag('checkout.step', 'payment')
    await chargeCard(order)          // к моменту продолжения область уже исчезла
    Buglapse.captureException(error)     // поймано без тега "checkout.step"
})

// ✅ ловите до await или задайте заново через setTag()/setContext() после него
Buglapse.withScope((scope) => {
    scope.setTag('checkout.step', 'payment')
    try {
        chargeCardSync(order)
    } catch (error) {
        Buglapse.captureException(error) // ещё внутри синхронного наложения
    }
})

Если перехват должен случиться после await, задайте теги/контекст глобально через setTag()/setContext() (и очистите/перезапишите их, когда операция закончится), а не полагайтесь на withScope().

environment и release ​

Эти два задаются отдельно — опциями environment/release в init() или атрибутами data-environment/data-release у script-тега, а не через setTag/setContext, — потому что это простые значения, а не объекты для разворачивания, и потому что панель обращается с ними особо: по environment работают фильтр environment: в поиске и условия в выражении фильтра, а release позволяет раскодировать минифицированный стектрейс в исходный код, если загружены соответствующие source maps. См. Настройка и Source maps.

Автоматический контекст ​

Часть контекста заполняют подключаемые интеграции, а не ваш вызов setContext():

  • DeviceIntegration один раз при подключении отправляет user agent браузера. Сервер разбирает его в browser.name/browser.version, os.name/os.version и device.type/device.manufacturer/device.model (последние три — только если user agent указывает конкретное устройство, например iPhone) в каждом событии — больше ничего о браузере посетителя (язык, часовой пояс, размер экрана, ...) не собирается и не хранится.
  • HttpContextIntegration заново проставляет request.url/request.referrer в каждое событие, потому что в SPA адрес может смениться между перехватами без перезагрузки.

Обе подключаемые и включаются в Настройки → Скрипт загрузчика проекта — см. Интеграции.

Контекст в панели ​

Страница события группирует развёрнутый контекст обратно по префиксу (order.* под заголовком «Order» и т.д.), превращая ключи через точку в подписи, — разобранные browser.*, os.* и device.* появляются там группами Browser / OS / Device. trace.*, replay.* и user.* в этот общий список не входят, потому что у каждого есть свой интерфейс (панель трейса/записи, карточка пользователя). Нажатие на любую строку ищет именно эту пару key:value — тем же синтаксисом, что вы бы набрали вручную:

order.currency:"USD"