いきなりコード
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を使いましょう。
wrap(ラップ)とは
スタックトレースの表示のためにエラーをラップします。
ラップすることで、返されるエラーには呼び出し元のファイルと行番号が含まれるようになります。
xerrors.Errorfを使用しています。
https://pkg.go.dev/golang.org/x/xerrors#Errorf
まとめ
errors.Is
はwrapされたエラーも判定できることがわかったので、デバックの容易性を上げるためにもどんどんラップしていきましょう!