errors.Join が返す error は interface { Unwrap() []error } を満たす
理由としては OTel トレース情報は Exporter に渡されて Datadog などに渡されるわけだが、モニタリングなどであるWindowで GraphQL エラー数などをカウントしているケースにおいて、実はノイズとなるエラーなのでエラーとして記録したくないというケースは多い
で、go-multierror や標準ライブラリのエラーの混在があるなか、選り分けをするケースにおいて Type Assertion を使って、これがわりと Go らしいのではないかと思った話
ざくっとコードは以下のような感じだ
code:errors.go
func unwrap(err error) []error {
if u, ok := err.(interface { WrappedErrors() []error }); ok {
return u.WrappedErrors()
}
// > A non-nil error returned by Join implements the Unwrap() []error method.
if u, ok := err.(interface { Unwrap() []error }); ok {
return u.Unwrap()
}
return nil
}
ガーと鳴けばアヒルであるといった喩えがそのままコードになったような表現だなと思った(日記
ちなみに標準ライブラリの errors.As, errors.Is も同じような選別の仕方で Unwrap するようになっている