Menangani kegagalan pengiriman webhook (failed webhooks) memerlukan kombinasi mekanisme percobaan ulang otomatis (retries), interval waktu mundur eksponensial (exponential backoff), antrean pesan mati (dead letter queue), dan desain payload yang idempoten untuk mencegah duplikasi data.
Kegagalan webhook umumnya terjadi karena server penerima mengalami down, timeout koneksi (>5 detik), atau mengembalikan kode status HTTP di luar rentang 2xx (seperti 500 Internal Server Error atau 404 Not Found). Tanpa sistem penanganan yang tepat, data event penting akan hilang secara permanen.
Strategi Penanganan Gagal Webhook Utama
| Strategi | Fungsi Utama | Implementasi Teknis |
|---|---|---|
| Automatic Retries | Mengirim ulang request yang gagal secara berkala. | Jadwalkan 3 hingga 5 kali percobaan dengan jeda waktu bertahap. |
| Exponential Backoff | Menghindari beban berlebih (thundering herd) pada server penerima. | Rumus jeda: $Delay = Base imes (Multiplier^{Attempt})$ detik. |
| Idempotency Keys | Mencegah pemrosesan data ganda akibat pengiriman ulang. | Sertakan header unik (UUID) per event yang disimpan di database penerima. |
| Dead Letter Queue (DLQ) | Menampung event yang gagal setelah batas maksimal percobaan tercapai. | Pindahkan payload ke tabel database khusus atau sistem antrean seperti RabbitMQ/SQS. |
Contoh Implementasi Retry dengan Exponential Backoff (Node.js)
Berikut adalah contoh kode implementasi logika pengiriman ulang webhook menggunakan bahasa pemrograman Node.js dengan penanganan error dan backoff eksponensial:
const axios = require('axios');
async function sendWebhookWithRetry(url, payload, maxRetries = 3) {
let attempt = 0;
let delay = 1000; // Mulai dengan 1 detik
while (attempt < maxRetries) {
try {
const response = await axios.post(url, payload, {
timeout: 5000,
headers: { 'X-Idempotency-Key': payload.eventId }
});
if (response.status >= 200 && response.status < 300) {
console.log(`Webhook berhasil dikirim pada percobaan ke-${attempt + 1}`);
return true;
}
} catch (error) {
attempt++;
console.warn(`Percobaan ${attempt} gagal: ${error.message}`);
if (attempt >= maxRetries) {
console.error('Batas maksimal percobaan tercapai. Memindahkan ke Dead Letter Queue.');
await moveToDeadLetterQueue(payload, error);
return false;
}
// Tunggu dengan durasi eksponensial sebelum mencoba lagi
await new Promise(resolve => setTimeout(resolve, delay));
delay *= 2; // Lipat gandakan durasi tunggu
}
}
}
async function moveToDeadLetterQueue(payload, error) {
// Simpan payload gagal ke database untuk dianalisis atau diproses manual
console.log('Menyimpan ke DLQ:', { payload, error: error.message });
}
Langkah-Langkah Troubleshooting Lapangan
- Verifikasi Log Sisi Pengirim & Penerima: Pastikan Anda mencatat (logging) HTTP Status Code, response body, dan timestamp dari setiap transaksi webhook.
- Cek Konfigurasi Firewall & SSL: Seringkali kegagalan disebabkan oleh sertifikat SSL yang kadaluwarsa atau aturan firewall pihak penerima yang memblokir IP address pengirim.
- Sediakan Dashboard Manual Retry: Buat antarmuka admin internal agar tim operasional dapat memicu ulang (retrigger) webhook dari Dead Letter Queue secara manual setelah perbaikan bug di sisi server penerima selesai dilakukan.
🔍 Orang Lain Juga Mencari Ini
Webhook Retry Strategy
Exponential Backoff Algorithm
Dead Letter Queue Implementation
Idempotency In Webhooks
Handling Webhook Timeouts
Webhook Security Signature Verification
Nodejs Webhook Error Handling
Webhook Delivery Best Practices
Rabbitmq Dead Letter Exchange
Aws Sqs Dead Letter Queue
Stripe Webhook Retry Logic
Http Status Codes For Webhooks
Debugging Failed Webhooks
Webhook Event Queuing
Asynchronous Webhook Processing