エラー処理

ルートハンドラやミドルウェアを実行中に発生するすべてのエラーをFiberがキャプチャし、ハンドラ関数に返すことが重要です。Fiberがこれらのエラーをキャプチャして処理するためです。

app.Get("/", func(c *fiber.Ctx) error {
    // エラーをFiberに渡す
    return c.SendFile("file-does-not-exist")
})

デフォルトではFiberはパニックエラーを処理しません。スタック内のハンドラで発生したパニックから回復し、Goプログラムをクラッシュさせないために、以下のようにRecoverミドルウェアを含める必要があります。

package main

import (
    "log"

    "github.com/gofiber/fiber/v2"
    "github.com/gofiber/fiber/v2/middleware/recover"
)

func main() {
    app := fiber.New()
	
	// パニックエラーをキャッチするためにrecoverミドルウェアを使用
    app.Use(recover.New())

    app.Get("/", func(c *fiber.Ctx) error {
        panic("This panic is caught by fiber")
    })

    log.Fatal(app.Listen(":3000"))
}

fiber.NewError()を使用してFiberのカスタムエラー構造体を利用し、追加のステータスコードを渡すことができます。メッセージの渡すことはオプションです。空の場合、ステータスコードのメッセージにデフォルトで設定されます(例: 404Not Found に等しい)。

app.Get("/", func(c *fiber.Ctx) error {
    // 503 Service Unavailable
    return fiber.ErrServiceUnavailable

    // 503 On vacation!
    return fiber.NewError(fiber.StatusServiceUnavailable, "On vacation!")
})

デフォルトのエラーハンドラ

Fiberはデフォルトのエラーハンドラを提供します。標準のエラーの場合、レスポンスは 500 Internal Server Error として送信されます。もしエラータイプが fiber.Error である場合、提供されたステータスコードとメッセージを使用してレスポンスが送信されます。

// デフォルトのエラーハンドラ
var DefaultErrorHandler = func(c *fiber.Ctx, err error) error {
    // デフォルトのステータスコードは 500
    code := fiber.StatusInternalServerError

    // もし *fiber.Error であれば、カスタムのステータスコードを取得
    var e *fiber.Error
    if errors.As(err, &e) {
        code = e.Code
    }

    // Content-Type を設定: text/plain; charset=utf-8
    c.Set(fiber.HeaderContentType, fiber.MIMETextPlainCharsetUTF8)

    // ステータスコードとエラーメッセージを返す
    return c.Status(code).SendString(err.Error())
}

カスタムエラーハンドラ

Fiberのインスタンスを初期化する際に、Configを使用してカスタムエラーハンドラを設定することができます。

ほとんどの場合、デフォルトのエラーハンドラで十分です。しかし、異なる種類のエラーをキャプチャして対応するアクションを取りたい場合、例えば通知メールを送信したり、エラーを中央集権システムにログしたりするなどの対応を取りたい場合は、カスタムエラーハンドラが非常に役立ちます。クライアントに対して、エラーページやJSONレスポンスを送信することもできます。

以下の例では、異なる種類のエラーに対してエラーページを表示する方法を示しています。

// カスタム構成を使用して新しいFiberインスタンスを作成
app := fiber.New(fiber.Config{
    // デフォルトのエラーハンドラをオーバーライド
    ErrorHandler: func(ctx *fiber.Ctx, err error) error {
        // デフォルトのステータスコードは 500
        code := fiber.StatusInternalServerError

        // もし *fiber.Error であれば、カスタムのステータスコードを取得
        var e *fiber.Error
        if errors.As(err, &e) {
            code = e.Code
        }

        // カスタムエラーページを送信
        err = ctx.Status(code).SendFile(fmt.Sprintf("./%d.html", code))
        if err != nil {
            // SendFileが失敗した場合
            return ctx.Status(fiber.StatusInternalServerError).SendString("Internal Server Error")
        }

        // ハンドラから戻る
        return nil
    },
})

// ...