Анализ Error Sessions (сессии с ошибками JavaScript)
Представьте: пользователь кладёт товар в корзину, нажимает «Оформить заказ» — и ничего не происходит. Консоль пестрит Cannot read property 'X' of undefined, checkout завис. Вы теряете деньги, а пользователь уходит к конкурентам. Мы помогаем выявить такие ошибки и устранить их до того, как они обнулят метрики.
Error Sessions — сессии, где произошла одна или несколько JavaScript-ошибок. Наш опыт показывает: без системного анализа вы пропускаете 60–80% критических багов, которые напрямую режут конверсию. Мы фильтруем, анализируем и приоритизируем эти сессии, используя Sentry и GA4. Sentry с Replay ускоряет отладку в 5–10 раз по сравнению с простым логгированием.
Настройка перехвата JavaScript-ошибок
Перехватываем все необработанные ошибки, Promise rejection и сбои fetch/XHR. Ключевой элемент — правильная настройка source maps: Sentry автоматически деобфусцирует стек, показывая исходный код, а не минифицированные строки. Пример интеграции:
// Перехват необработанных ошибок
window.addEventListener('error', function(event) {
const errorInfo = {
message: event.message,
source: event.filename?.split('/').pop(),
line: event.lineno,
col: event.colno,
stack: event.error?.stack?.slice(0, 500),
page: window.location.pathname,
user_agent: navigator.userAgent.slice(0, 100)
}
// Отправить в GA4
gtag('event', 'js_error', errorInfo)
// Отправить в Sentry/Bugsnag
Sentry.captureException(event.error, {
extra: errorInfo
})
})
// Перехват unhandled Promise rejections
window.addEventListener('unhandledrejection', function(event) {
gtag('event', 'promise_rejection', {
message: event.reason?.message || String(event.reason),
page: window.location.pathname
})
})
// Перехват ошибок в fetch/XHR
const originalFetch = window.fetch
window.fetch = async function(...args) {
try {
const response = await originalFetch(...args)
if (!response.ok) {
gtag('event', 'fetch_error', {
url: args[0].toString().split('?')[0],
status: response.status,
page: window.location.pathname
})
}
return response
} catch (err) {
gtag('event', 'fetch_exception', {
url: args[0].toString().split('?')[0],
message: err.message
})
throw err
}
}
Более подробно о window.onerror читайте в документации MDN. Как указано в документации Sentry, интеграция с source maps и Replay ускоряет отладку в 5–10 раз по сравнению с обычным логированием.
Интеграция Sentry с Replay и Tracing
Для глубокого анализа подключаем Sentry с Replay и Tracing. Replay записывает сессию до момента ошибки, что позволяет увидеть действия пользователя. Пример конфигурации:
// sentry.init.js
import * as Sentry from '@sentry/browser'
import { BrowserTracing } from '@sentry/tracing'
Sentry.init({
dsn: 'https://[email protected]/yyy',
integrations: [
new BrowserTracing(),
new Sentry.Replay({
maskAllText: false,
blockAllMedia: false
})
],
tracesSampleRate: 0.1, // 10% для performance
replaysSessionSampleRate: 0.05, // 5% сессий записывать
replaysOnErrorSampleRate: 1.0, // 100% при ошибке
beforeSend(event) {
// Добавить контекст пользователя
event.user = {
id: currentUser?.id,
segment: currentUser?.plan
}
return event
}
})
Как ошибки влияют на конверсию?
Мы строим SQL-запросы, сравнивающие CVR сессий с ошибками и без. Типичный результат: сессии с ошибками конвертируют в 3+ раза хуже. Пример кода:
def analyze_error_impact(analytics_db):
# Сравнить конверсию сессий с ошибками vs без
result = analytics_db.query("""
WITH session_errors AS (
SELECT
session_id,
COUNT(*) as error_count,
MAX(CASE WHEN event_name = 'purchase' THEN 1 ELSE 0 END) as converted
FROM events
WHERE date >= CURRENT_DATE - INTERVAL '7 days'
AND event_name IN ('js_error', 'purchase')
GROUP BY session_id
),
all_sessions AS (
SELECT session_id,
MAX(CASE WHEN event_name = 'purchase' THEN 1 ELSE 0 END) as converted
FROM events
WHERE date >= CURRENT_DATE - INTERVAL '7 days'
GROUP BY session_id
)
SELECT
'with_errors' AS segment,
COUNT(*) AS sessions,
SUM(converted) AS conversions,
ROUND(AVG(converted::float) * 100, 2) AS cvr
FROM session_errors WHERE error_count > 0
UNION ALL
SELECT
'without_errors',
COUNT(*),
SUM(a.converted),
ROUND(AVG(a.converted::float) * 100, 2)
FROM all_sessions a
LEFT JOIN session_errors se ON a.session_id = se.session_id
WHERE se.session_id IS NULL
""")
return result
# Типичный результат:
# with_errors: 1.2% CVR
# without_errors: 3.8% CVR
# Ошибки снижают конверсию в 3+ раза
| Сегмент | Сессии | Конверсии | CVR |
|---|---|---|---|
| С ошибками | 12450 | 149 | 1.2% |
| Без ошибок | 112050 | 4258 | 3.8% |
Разница — в 3.2 раза. Если ваш средний чек 3000 ₽, потери за неделю составляют более 1.2 млн ₽.
Сравнение инструментов мониторинга
| Инструмент | Source maps | Replay | Интеграция с GA4 | Цена |
|---|---|---|---|---|
| Sentry | Да | Да | Через API | Бесплатно до 5k событий/мес |
| Bugsnag | Да | Нет | Через API | От $29/мес |
| LogRocket | Да | Да | Нет | От $39/мес |
| GA4 | Нет | Нет | Встроено | Бесплатно |
Sentry — оптимальный выбор для глубокого анализа: он сочетает source maps, Replay и гибкую интеграцию с GA4. По сравнению с GA4, Sentry лучше подходит для отладки, поскольку предоставляет полный стек и Replay, что сокращает время поиска причины в 5–10 раз.
Как приоритизировать исправление ошибок?
Мы используем метрику affected_users × conversion_impact. Ошибки в модулях checkout/payment получают вес 3, остальные — 1. Пример:
def prioritize_errors(sentry_api, project_slug):
"""Приоритет = affected_users × conversion_impact"""
issues = sentry_api.get_issues(project_slug, limit=50)
for issue in issues:
affected_users = issue['userCount']
# Ошибки в checkout/payment — высокий приоритет
is_critical = any(p in issue['culprit'] for p in
['checkout', 'payment', 'cart', 'form'])
issue['priority_score'] = affected_users * (3 if is_critical else 1)
return sorted(issues, key=lambda x: x['priority_score'], reverse=True)
Типичные критические ошибки
-
Cannot read property 'X' of undefined— race condition при асинхронной загрузке -
Network Errorв fetch — API недоступен, нет retry логики -
PaymentRequestUpdateEvent— ошибки Payment Request API на iOS Safari -
ChunkLoadError— устаревший кэш после деплоя (решается:window.location.reload())
Кейс из практики: как подняли CVR на 25%
На одном проекте (интернет-магазин электроники) после деплоя новой версии checkout-модуля конверсия упала с 3.5% до 1.1%. Выяснилось, что в 40% сессий возникала ошибка Cannot read property 'price' of undefined из-за изменения формата ответа API. Sentry показал, что ошибка затрагивает 15k пользователей в день. После фикса и повторного деплоя CVR вернулась к 3.5% через 2 дня. Потери за 3 дня составили ~900 заказов.
Что входит в услугу
- Настройка перехвата всех JS-ошибок (включая source maps)
- Интеграция Sentry с Replay и Tracing
- Создание событий в GA4 для конверсионного анализа
- Дашборды влияния ошибок на CVR и выручку
- Приоритизированный список багов с рекомендациями
- Документация по интеграции и доступ к дашбордам
- Поддержка в течение месяца после внедрения
Процесс работы
- Аудит текущего мониторинга: проверяем, какие ошибки уже перехватываются.
- Настройка инструментов: устанавливаем Sentry, дорабатываем GA4 events.
- Сбор данных: 7 дней накопления статистики по Error Sessions.
- Анализ и приоритизация: строим SQL-отчёты, вычисляем влияние на конверсию.
- Отчёт и исправление: передаём вам список багов с указанием критичности, помогаем с правками.
- Контроль: после исправлений повторяем анализ, чтобы убедиться в росте CVR.
Сроки и результаты
Первые результаты — уже через 2 рабочих дня: вы видите дашборд с Error Sessions и их влиянием. Полный цикл анализа и приоритизации — от 5 до 7 дней. Конкретная стоимость зависит от объёма проекта (количество страниц, интеграций), поэтому мы рассчитываем её индивидуально. Свяжитесь — оценим ваш проект бесплатно.
Почему выбирают нас
Наш опыт — более 10 лет в frontend-разработке и мониторинге. Мы работали с проектами, где CVR выросла на 25% только за счёт устранения JS-ошибок. Используем только проверенные инструменты: Sentry, GA4, Grafana. Даём гарантию на корректную работу интеграций. Закажите аудит — получите консультацию с детальным разбором ваших Error Sessions. Свяжитесь с нами — мы подготовим индивидуальное предложение.







