Middleware: Recover dari Panic
Menangkap panic dengan defer dan recover agar satu bug tidak membuat client menerima koneksi putus.
Apa itu panic?
Panic adalah kesalahan fatal saat program berjalan, misalnya mengakses indeks di luar batas slice atau memakai pointer nil. Jika tidak ditangani, panic menghentikan goroutine yang sedang berjalan.
Untuk server HTTP, Go cukup baik: panic di satu request tidak mematikan seluruh server. Tetapi client akan menerima koneksi terputus tanpa jawaban — bukan pesan error yang rapi. Middleware Recover memperbaikinya.
defer dan recover
defer— menjalankan fungsi tepat sebelum fungsi pembungkusnya selesai, termasuk saat terjadi panic.recover()— dipanggil di dalam fungsi yang di-defer; mengembalikan nilai panic (dan menghentikan panic itu), ataunilbila tidak ada panic.
func Recover(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if rec := recover(); rec != nil {
fmt.Println("PANIC ditangkap:", rec)
writeError(w, http.StatusInternalServerError, "terjadi kesalahan pada server")
}
}()
next.ServeHTTP(w, r)
})
}
Alurnya
defermendaftarkan "jaring pengaman".next.ServeHTTPmenjalankan handler. Jika handler panic, eksekusi melompat ke fungsi yang di-defer.recover()menangkap panic, kita mencatatnya, lalu menjawab 500 Internal Server Error dengan format JSON yang sama seperti error lain.
Urutan memasang middleware
Middleware bisa ditumpuk: Logging(Recover(mux)). Request melewati Logging dulu, lalu Recover, lalu mux. Taruh Recover cukup di luar agar menangkap panic dari middleware lain di dalamnya.