Моніторинг мережевих помилок у мобільному додатку
Уявіть: 3:00 ночі, бекенд відповідає 502. 8% користувачів бачать порожній екран, частина видаляє додаток. Ми стикаємося з цим щодня — продакшн без відстеження мережевих помилок втрачає аудиторію. За допомогою Sentry перехоплюємо такі сценарії на ранньому етапі, групуємо помилки за fingerprint і налаштовуємо алерти, щоб не пропустити жодного збою.
Мережеві помилки бувають різними: від втрати з'єднання до парсингу відповіді. Кожна категорія потребує своєї стратегії. Нижче — класифікація з пріоритетами, заснована на досвіді десятків проєктів (ми маємо 5+ років досвіду та 50+ успішних проєктів).
| Тип помилки | Приклад | Пріоритет |
|---|---|---|
| Connectivity | Network request failed, timeout |
Високий — втрата з'єднання |
| 4xx клієнтські | 401, 403, 404, 422 | Середній — часто очікувані |
| 5xx серверні | 500, 502, 503, 504 | Високий — проблема на бекенді |
| Parse error | JSON decode failure | Високий — breaking change |
| SSL/TLS | Certificate pinning failure | Критичний — можлива атака |
Переваги Sentry перед кастомним логуванням
Кастомне логування часто створює тисячі дублюваних тікетів. Sentry групує їх за fingerprint — це скорочує час аналізу в 5–10 разів. Крім того, Sentry надає контекст: пристрій, версія ОС, трейси запитів. Згідно з документацією Sentry, правильне налаштування групування знижує кількість інцидентів у 3.3 рази (на 70%). Ми використовуємо Sentry не перший рік — це перевірене рішення для продакшну. Економія на підтримці інцидентів може сягати $15,000 на місяць.
Як перехопити мережеві запити в React Native?
@sentry/react-native автоматично патчить fetch та XMLHttpRequest. За замовчуванням включає Performance трейси, але помилки не логує автоматично. Ось конфігурація:
import * as Sentry from '@sentry/react-native';
Sentry.init({
dsn: 'https://[email protected]/yyy',
tracesSampleRate: 0.1, // 10% запитів для Performance
integrations: [
new Sentry.ReactNativeTracing({
traceFetch: true,
traceXHR: true,
tracingOrigins: ['api.yourapp.com', 'cdn.yourapp.com'],
}),
],
});Для явного логування мережевих помилок — обгортка над fetch:
Приклад коду обгортки fetch
export async function monitoredFetch(
url: string,
options?: RequestInit
): Promise<Response> {
const startTime = Date.now();
try {
const response = await fetch(url, options);
const duration = Date.now() - startTime;
if (!response.ok) {
Sentry.captureMessage(`HTTP ${response.status}: ${url}`, {
level: response.status >= 500 ? 'error' : 'warning',
extra: {
status: response.status,
duration,
method: options?.method ?? 'GET',
endpoint: new URL(url).pathname,
},
fingerprint: [`http-${response.status}`, new URL(url).pathname],
});
}
return response;
} catch (error) {
Sentry.captureException(error, {
extra: {
url,
duration: Date.now() - startTime,
},
tags: {
error_type: 'network_connectivity',
},
});
throw error;
}
}fingerprint — критично важливий. Без нього Sentry створює окремий issue для кожного URL з помилкою. З fingerprint ['http-500', '/api/orders'] всі 500-ті помилки на /api/orders групуються в один issue.
Як налаштувати fingerprint для групування?
У наведеному коді ми використовуємо статус відповіді та шлях endpoint. Якщо потрібно об'єднати помилки за іншою ознакою — змініть масив. Наприклад, для аутентифікаційних помилок: ['auth-4xx'].
Breadcrumbs: контекст перед помилкою
Breadcrumbs показують, що відбувалося до мережевої помилки: які екрани відкривав користувач, які дії виконував. За замовчуванням зберігаються останні 100 breadcrumbs — цього достатньо для довгих сесій. Ось як додати breadcrumb при навігації:
// Додаємо breadcrumb при навігації
navigation.addListener('state', (e) => {
Sentry.addBreadcrumb({
category: 'navigation',
message: `Navigate to ${e.data.state.routes[e.data.state.index].name}`,
level: 'info',
});
});Завдяки breadcrumbs час на локалізацію проблеми скорочується з годин до хвилин: ви бачите не просто помилку, а послідовність дій користувача.
Як відокремити offline-помилки від серверних?
Offline-помилки потрібно відрізняти від серверних. Користувач у метро — не проблема бекенду:
import NetInfo from '@react-native-community/netinfo';
let isConnected = true;
NetInfo.addEventListener(state => {
isConnected = state.isConnected ?? true;
});
// В monitoredFetch, при catch:
if (!isConnected) {
// Не відправляємо в Sentry — це очікуваний offline
throw new OfflineError('No network connection');
}
// Інакше — реальна помилка, логуємо
Sentry.captureException(error, {
tags: { connectivity: 'online' }
}); Порівняння підходів до алертингу
| Метод | Чутливість | Час реакції |
|---|---|---|
| Ручний моніторинг логів | Низька | Години |
| Sentry Alerts з порогом | Висока | Хвилини |
Як налаштувати алерти в Sentry?
Sentry Alerts за умовою: count(event) > 50 per 5min для http-500 → Slack/PagerDuty. Error rate вище baseline → alert. Для продакшну це має працювати 24/7. Ось покрокова інструкція:
- Відкрийте розділ Alerts → Create Alert.
- Виберіть тип: Issues (кількість помилок).
- Задайте критерій: фільтр за рівнем (
error), тегам (endpoint). - Вкажіть поріг: наприклад, 50 подій за 5 хвилин.
- Налаштуйте канал: Slack, PagerDuty, email.
- Вкажіть інтервал silence (щоб уникнути спаму).
Готово. Алерти будуть автоматично сповіщати команду про сплески помилок.
Що входить у налаштування під ключ?
Ми гарантуємо коректне налаштування моніторингу. До роботи входить:
- Інтеграція Sentry в додаток (будь-який стек: React Native, Flutter, нативний).
- Налаштування fingerprint для всіх endpoint.
- Додавання offline-детектування та breadcrumbs.
- Розробка правил алертингу та інтеграція з вашим месенджером.
- Документація для розробників.
- Навчання команди (1–2 дзвінки).
- Підтримка протягом місяця після запуску.
Ми налаштовуємо моніторинг для продакшн-додатків вже 5+ років. Серед наших клієнтів — фінтех, e-commerce та SaaS (50+ проєктів). Вартість налаштування від $2,000, окупається за 1–2 місяці. Оцінимо ваш проєкт — напишіть нам.
Оцінка
Налаштування Sentry з монітором мережевих запитів, fingerprinting, offline-детектом та алертами: 1–2 тижні. Вартість розраховується індивідуально. Хочете захистити свій додаток? Заповніть форму зворотного зв'язку — ми зв'яжемося протягом дня.







