Error Monitoring (Sentry-style) — Debugging

Error Monitoring Tools Error monitoring adalah praktik melacak error yang terjadi di production secara otomatis — tanpa harus menunggu laporan dari user. Tool…

Error monitoring adalah tool yang menangkap error di aplikasi yang sedang dipakai user (production), lalu mengirimkannya otomatis ke satu dashboard, lengkap dengan stack trace dan konteksnya. Contohnya Sentry, Rollbar, Bugsnag, dan Datadog. Bayangin pusat pengaduan ojek online. Ratusan penumpang melapor "aplikasi error waktu bayar", tapi petugasnya gak bikin ratusan tiket: laporan yang sama digabung jadi satu tiket bertuliskan "dilaporkan 47 kali", dan tiap laporan membawa catatan apa yang dilakukan penumpang sebelum masalahnya muncul. Bedanya, di sini laporannya dikirim aplikasi sendiri, tanpa menunggu user mengeluh.

🧪 Tebakan cepat: tiga error tertangkap. Dua kali Cannot read property dari login.js baris 45 (user u1 lalu u2), dan sekali Network error dari api.js. Di dashboard ada berapa issue, dan berapa count issue pertama? Jawabannya ada di bagian "Fingerprint: error yang sama jadi satu issue".

Kenapa butuh error monitoring

console.log dan DevTools cuma jalan di laptopmu. Error yang terjadi di HP user gak pernah kamu lihat, dan kebanyakan user gak melapor: mereka cuma menutup aplikasinya. Error monitoring memasang sebuah SDK (library kecil dari tool-nya) di aplikasimu. Setiap ada error yang gak ditangkap, SDK itu mengirim satu event, yaitu satu laporan error, ke server tool-nya.

Isi satu event kira-kira begini:

Breadcrumb dicatat SDK Sentry otomatis: klik, pindah halaman, request fetch, dan isi console. Contohnya, sebelum login gagal:

navigation  /  →  /login
ui.click    button#masuk
fetch       POST /api/login  200
error       TypeError: Cannot read property

Dari jejak ini kamu tahu: request login-nya berhasil (200), jadi masalahnya ada di kode yang membaca jawabannya, bukan di server.

Fingerprint: error yang sama jadi satu issue

Kalau 500 user kena error yang sama, kamu gak mau 500 notifikasi. Tool-nya menghitung fingerprint (sidik jari) tiap event. Event dengan fingerprint yang sama digabung jadi satu issue, dan angka count-nya naik. Sentry memakai stack trace sebagai fingerprint, dan kalau stack trace-nya gak ada, dia memakai jenis dan pesan error-nya. Di latihan, fingerprint-nya disederhanakan: baris pertama error.stack, atau error.message kalau stack-nya kosong.

Ini tiga error dari tebakan tadi, ditangkap satu per satu:

# Error Context Fingerprint Hasil
1 Cannot read property, di login.js:45 u1, env: prod TypeError: Cannot read property issue baru, count 1
2 Cannot read property, di login.js:45 u2, env: prod TypeError: Cannot read property sama, count jadi 2
3 Network error, di api.js:12 u1, env: staging Error: Network error issue baru, count 1

Tiga laporan, dua issue, dan issue pertama punya count 2. Itu jawaban tebakannya.

Bikin monitor seperti Sentry

function createMonitor(release) {
  const events = [];
  let nextId = 1;

  function generateFingerprint(error) {
    // baris pertama stack trace, atau pesannya kalau stack kosong
    return error.stack ? error.stack.split('\n')[0] : error.message;
  }

  return {
    capture(error, context) {
      const fingerprint = generateFingerprint(error);
      const sudahAda = events.find((e) => e.fingerprint === fingerprint);
      if (sudahAda) {
        sudahAda.count++; // digabung, bukan event baru
        return sudahAda;
      }
      const event = {
        id: nextId++, message: error.message, fingerprint, release,
        userId: context.userId, url: context.url, tags: context.tags || {},
        timestamp: new Date().toISOString(), count: 1,
      };
      events.push(event);
      return event;
    },
    getEvents: () => events,
    getEventsByTag: (key, value) => events.filter((e) => e.tags[key] === value),
    getTopErrors: (n) => [...events].sort((a, b) => b.count - a.count).slice(0, n),
  };
}

const mon = createMonitor('v1.2.3');
const errLogin = { message: 'Cannot read property', stack: 'TypeError: Cannot read property\n  at login.js:45' };
mon.capture(errLogin, { userId: 'u1', url: '/login', tags: { env: 'prod' } });
mon.capture(errLogin, { userId: 'u2', url: '/login', tags: { env: 'prod' } });
mon.capture(
  { message: 'Network error', stack: 'Error: Network error\n  at api.js:12' },
  { userId: 'u1', tags: { env: 'staging' } }
);

console.log(mon.getEvents().length);                  // 2
console.log(mon.getEvents()[0].count);                // 2
console.log(mon.getEventsByTag('env', 'prod').length); // 1
console.log(mon.getTopErrors(1)[0].message);          // Cannot read property

Pasang Sentry sungguhan

import * as Sentry from '@sentry/browser';

Sentry.init({
  dsn: 'https://[email protected]/456', // alamat proyekmu di Sentry
  release: '[email protected]',
  environment: 'production',
});

Sentry.setUser({ id: 'u1' });
Sentry.setTag('env', 'prod');

Error yang sudah ditangkap try/catch

Error yang kamu tangkap sendiri gak pernah sampai ke SDK. Laporkan manual dengan Sentry.captureException(error):

try {
  await bayar(pesanan);
} catch (error) {
  Sentry.captureException(error); // tetap terkirim, lengkap dengan stack trace
  tampilkanPesan('Pembayaran gagal, coba lagi ya.');
}

Untuk kejadian yang bukan error, pakai Sentry.captureMessage('kupon kedaluwarsa dipakai'). Untuk menambah jejak sendiri, pakai Sentry.addBreadcrumb({ category: 'checkout', message: 'pilih QRIS', level: 'info' }).

⚠️ Jebakan yang sering ketemu

TL;DR: Error monitoring (misalnya Sentry) mengirim tiap error di production sebagai event: message, stack trace, release, user, tags, dan breadcrumbs (jejak klik, navigasi, fetch sebelum error). Event dengan fingerprint sama digabung jadi satu issue dan count-nya naik, jadi 3 laporan bisa jadi 2 issue. Di latihan, fingerprint = baris pertama error.stack atau error.message, getEventsByTag menyaring tags[key] === value, dan getTopErrors(n) mengurutkan salinan dari count terbesar. Pasang Sentry.init dengan release dan environment, dan error yang kamu tangkap sendiri laporkan dengan Sentry.captureException(error).

Yang akan kamu pelajari