Episode ini membahas penanganan error di Fiber v3: ErrorHandler default, custom error handler, fungsi fiber.NewError, perbedaan fiber.Error dan fiber.RecoverError, serta middleware Logger dengan template kustom dan format waktu.

Error handling adalah pembeda antara API yang menyebalkan dan API yang profesional. Episode 9 membahas penanganan error di Fiber v3: bagaimana ErrorHandler default bekerja, cara menulis custom error handler, dan bagaimana fiber.NewError membantu mengembalikan error terstruktur.
Selain itu kita akan menguasai middleware Logger — menyesuaikan format output, memilih informasi yang dicatat, dan mengatur format waktu. Kombinasi keduanya membuat aplikasi mudah di-debug dan mudah dimonitor.
Ketika sebuah handler mengembalikan error, Fiber meneruskan error tersebut ke ErrorHandler. Secara default, Fiber mengembalikan respons sesuai status error atau status 500 jika error biasa:
app := fiber.New()
app.Get("/", func(c fiber.Ctx) error {
return fiber.NewError(fiber.StatusNotFound, "Halaman tidak ada")
})Di Fiber v3, default ErrorHandler dikirim sebagai *fiber.Error. Kode status 404 direspons dengan body {"code":404,"message":"Halaman tidak ada"} — lengkap dengan code dan message. Jika handler mengembalikan error biasa, status default-nya 500.
Fiber v3 mendefinisikan dua tipe error internal. Mengenalinya penting saat menulis error handler:
type Error struct {
Code int
Message string
}
type RecoverError struct {
Code int
Message string
}fiber.Error berisi Code dan Message untuk error yang dikembalikan handler. fiber.RecoverError adalah pembungkus khusus untuk error yang ditangkap middleware Recover dari panic. Keduanya bisa dibedakan dengan errors.As di dalam custom error handler.
Kalian bisa mengganti error handler global lewat konfigurasi. Ini penting untuk memastikan format respons konsisten di seluruh aplikasi:
app := fiber.New(fiber.Config{
ErrorHandler: func(c fiber.Ctx, err error) error {
code := fiber.StatusInternalServerError
var fe *fiber.Error
if errors.As(err, &fe) {
code = fe.Code
}
if code == fiber.StatusNotFound {
return c.Status(code).SendString("404 - halaman tidak ditemukan")
}
return c.Status(code).JSON(fiber.Map{
"code": code,
"message": err.Error(),
})
},
})Custom handler menerima c fiber.Ctx dan err error. Ia bisa memeriksa tipe error, menentukan status code, dan memilih format respons — misalnya halaman HTML untuk 404 dan JSON untuk error API.
Error handler tidak harus global. Fiber v3 memungkinkan mengatur error handler khusus per route dengan fiber.RouteAttrErrorHandler:
app.Get("/admin/:id", func(c fiber.Ctx) error {
return fiber.NewError(fiber.StatusForbidden, "akses ditolak")
}, fiber.RouteAttrErrorHandler(func(c fiber.Ctx, err error) error {
return c.Status(fiber.StatusUnauthorized).SendString("login dulu")
}))Dengan RouteAttrErrorHandler, error dari route /admin/:id direspons oleh handler khusus — handler global tetap berlaku untuk route lain. Ini berguna untuk area dengan kontrak respons yang berbeda, misalnya API dan halaman web dalam satu aplikasi.
Fungsi fiber.NewError(code, message) membuat *fiber.Error dengan kode status dan pesan. Error ini bisa menyimpan argumen tambahan:
func findUser(id int) (*User, error) {
if id < 1 {
return nil, fiber.NewError(fiber.StatusBadRequest, "ID tidak valid", "id", id)
}
user, ok := users[id]
if !ok {
return nil, fiber.NewError(fiber.StatusNotFound, "User tidak ditemukan")
}
return &user, nil
}fiber.NewError(400, "...", "id", id) menyisipkan pasangan argumen untuk konteks tambahan. Saat error ini diteruskan ke ErrorHandler, nilai argumen bisa diakses untuk membangun pesan respons yang lebih kaya.
logger.New() punya banyak opsi template. Kalian bisa menulis format sendiri memakai variabel seperti {{pid}}, {{ip}}, {{method}}, {{path}}, {{status}}, dan {{latency}}:
app.Use(logger.New(logger.Config{
Format: "[{{time}}] {{ip}} {{method}} {{path}} status={{status}} lat={{latency}}\n",
TimeFormat: "2006-01-02 15:04:05",
TimeZone: "Asia/Jakarta",
}))Template menentukan apa yang dicatat. TimeFormat mengatur format waktu, TimeZone mengatur zona waktu — defaultnya UTC. Kombinasi ini menghasilkan log yang mudah dibaca dan konsisten dengan zona lokal.
curl http://localhost:3000/tidak-ada
curl http://localhost:3000/admin/1Request pertama memicu custom error handler global — halaman 404 - halaman tidak ditemukan. Request kedua memicu RouteAttrErrorHandler khusus admin dengan respons login dulu. Di terminal, middleware logger mencatat kedua request dengan template kustom.
Inti yang harus dibawa pulang:
ErrorHandler default mengembalikan *fiber.Error dengan code dan message.fiber.Config{ErrorHandler}.fiber.NewError(code, message, args...) membuat error terstruktur.fiber.Error dan fiber.RecoverError bisa dibedakan dengan errors.As.fiber.RouteAttrErrorHandler memberi error handler khusus per route.logger bisa dikustomisasi lewat Format, TimeFormat, dan TimeZone.Di episode 10 selanjutnya kita membahas context dan ekstensi request — semua method di fiber.Ctx, penerusan proxy dan sendStream, serta ekstensi request seperti nilai khusus pada port dan namespace.