Edited at

xerrorsパッケージでラップしたエラーをswitchで判別する #golang


TL;DR

switchの条件式をxerrors.Unwrap(err).(type)にする。


問題

xerrors.Errorfでラップしたエラーをerrors.Cause(err).(type)で条件分岐させようとしたが、defaultに振り分けられてしまった。

err := xerrors.Errorf("my error: %w", &MyError{})

switch errors.Cause(err).(type) {
case *MyError:
fmt.Println("my error")
default:
fmt.Println("other")
}
//-> other

The Go Playground


解決方法

試行錯誤した結果、switchの条件式をxerrors.Unwrap(err).(type)にすることで目的の処理をさせることができた。

err := xerrors.Errorf("my error: %w", &MyError{})

switch xerrors.Unwrap(err).(type) {
case *MyError:
fmt.Println("my error")
default:
fmt.Println("other")
}
//-> my error

The Go Playground


おまけ

ラップしたエラーを取り出すときはxerrors.Asを使う。

switch xerrors.Unwrap(err).(type) {

case *MyError:
var e *MyError
xerrors.As(err, &e)
fmt.Printf("%v\n", e)
default:
fmt.Println("other")
}

The Go Playground


リンク

xerrors godoc