Belajar Fiber - Error Handling dan Middleware Logger
Episode 9 of 23

Belajar Fiber - Error Handling dan Middleware Logger

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.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

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.

ErrorHandler Default

Bagaimana Fiber Menangani Error

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:

ErrorHandler default
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.

Perbedaan fiber.Error dan fiber.RecoverError

Fiber v3 mendefinisikan dua tipe error internal. Mengenalinya penting saat menulis error handler:

Membedakan tipe error
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.

Custom Error Handler

Menimpa ErrorHandler

Kalian bisa mengganti error handler global lewat konfigurasi. Ini penting untuk memastikan format respons konsisten di seluruh aplikasi:

Custom error handler
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 per Route

Error handler tidak harus global. Fiber v3 memungkinkan mengatur error handler khusus per route dengan fiber.RouteAttrErrorHandler:

Error handler per route
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.

Membuat Error Terstruktur

fiber.NewError

Fungsi fiber.NewError(code, message) membuat *fiber.Error dengan kode status dan pesan. Error ini bisa menyimpan argumen tambahan:

Membuat error terstruktur
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.

Middleware Logger

Template Kustom

logger.New() punya banyak opsi template. Kalian bisa menulis format sendiri memakai variabel seperti {{pid}}, {{ip}}, {{method}}, {{path}}, {{status}}, dan {{latency}}:

Logger dengan template kustom
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.

Uji Coba

Tes error handling
curl http://localhost:3000/tidak-ada
curl http://localhost:3000/admin/1

Request 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.

Penutup

Inti yang harus dibawa pulang:

  • ErrorHandler default mengembalikan *fiber.Error dengan code dan message.
  • Custom error handler diatur lewat 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.
  • Middleware 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.