コンテンツへスキップ

wrapされたエラーもerrors.Isで判定できるよ

いきなりコード

package main

import (
    "errors"
    "fmt"

    "golang.org/x/xerrors"
)

var (
    NotFoundError = errors.New("not found")
    InvalidError  = errors.New("invalid")
    InternalError = errors.New("internal")
)

func main() {
    err := invalid()
    if err != nil {
        fmt.Println(err)
        fmt.Println(errors.Is(err, NotFoundError))
        fmt.Println(errors.Is(err, InvalidError))
        fmt.Println(errors.Is(err, InternalError))
    }

    err = internal()
    if err != nil {
        fmt.Println(err)
        fmt.Println(errors.Is(err, NotFoundError))
        fmt.Println(errors.Is(err, InvalidError))
        fmt.Println(errors.Is(err, InternalError))
    }
}

func invalid() error {
    //
    return xerrors.Errorf("wrap: %w", InvalidError)
}

func internal() error {
    //
    return xerrors.Errorf("wrap: %w", InternalError)
}

出力

wrap: invalid
false
true
false
wrap: internal
false
false
true

エラーの同一性の判定

エラーが同一か判定するためにerrors.Isを使用します。
errのツリーに含まれるエラーがtargetにマッチするかどうかを判定してくれるメソッドです。
errが複数のエラーをラップしている場合、その子も探索してくれます。

※xerrors.Isは非推奨になりました。errors.Isを使いましょう。

https://pkg.go.dev/errors#Is

wrap(ラップ)とは

スタックトレースの表示のためにエラーをラップします。
ラップすることで、返されるエラーには呼び出し元のファイルと行番号が含まれるようになります。

xerrors.Errorfを使用しています。

https://pkg.go.dev/golang.org/x/xerrors#Errorf

まとめ

errors.Isはwrapされたエラーも判定できることがわかったので、デバックの容易性を上げるためにもどんどんラップしていきましょう!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です