Go1.13でのエラーハンドリングの挙動をコードを書いてまとめました
package main
import (
"errors"
"fmt"
)
func main() {
cause := &CauseError{}
wrapCause := fmt.Errorf("wrap cause: %w", cause)
wrapFirst := fmt.Errorf("wrap first: %w", wrapCause)
wrapSecond := fmt.Errorf("wrap second: %w", wrapFirst)
fmt.Printf("cause = %+v\n", cause)
fmt.Printf("wrapCause = %+v\n", wrapCause)
fmt.Printf("wrapFirst = %+v\n", wrapFirst)
fmt.Printf("wrapSecond = %+v\n", wrapSecond)
fmt.Printf("errors.Is(wrapSecond, cause) = %+v\n", errors.Is(wrapSecond, cause))
fmt.Printf("errors.Is(wrapFirst, cause) = %+v\n", errors.Is(wrapFirst, cause))
fmt.Printf("errors.Is(wrapFirst, wrapCause) = %+v\n", errors.Is(wrapFirst, wrapCause))
fmt.Printf("errors.Is(wrapSecond, &CauseError{}) = %+v\n", errors.Is(wrapSecond, &CauseError{}))
fmt.Printf("errors.Is(wrapFirst, &CauseError{}) = %+v\n", errors.Is(wrapFirst, &CauseError{}))
fmt.Printf("errors.Unwrap(wrapSecond) = %+v\n", errors.Unwrap(wrapSecond))
fmt.Printf("errors.Unwrap(wrapFirst) = %+v\n", errors.Unwrap(wrapFirst))
fmt.Printf("errors.Unwrap(wrapCause) = %+v\n", errors.Unwrap(wrapCause))
fmt.Printf("errors.Unwrap(cause) = %+v\n", errors.Unwrap(cause))
var c error
fmt.Printf("errors.As(wrapSecond, &c) = %+v\n", errors.As(wrapSecond, &c))
fmt.Printf("c = %+v\n", c)
fmt.Printf("errors.As(wrapFirst, &c) = %+v\n", errors.As(wrapFirst, &c))
fmt.Printf("c = %+v\n", c)
fmt.Printf("errors.As(wrapCause, &c) = %+v\n", errors.As(wrapCause, &c))
fmt.Printf("c = %+v\n", c)
fmt.Printf("errors.As(cause, &c) = %+v\n", errors.As(cause, &c))
fmt.Printf("c = %+v\n", c)
}
type CauseError struct {
}
func (t *CauseError) Error() string {
return "cause error"
}
出力結果
cause = cause error
wrapCause = wrap cause: cause error
wrapFirst = wrap first: wrap cause: cause error
wrapSecond = wrap second: wrap first: wrap cause: cause error
errors.Is(wrapSecond, cause) = true
errors.Is(wrapFirst, cause) = true
errors.Is(wrapFirst, wrapCause) = true
errors.Is(wrapSecond, &CauseError{}) = true
errors.Is(wrapFirst, &CauseError{}) = true
errors.Unwrap(wrapSecond) = wrap first: wrap cause: cause error
errors.Unwrap(wrapFirst) = wrap cause: cause error
errors.Unwrap(wrapCause) = cause error
errors.Unwrap(cause) = <nil>
errors.As(wrapSecond, &c) = true
c = wrap second: wrap first: wrap cause: cause error
errors.As(wrapFirst, &c) = true
c = wrap first: wrap cause: cause error
errors.As(wrapCause, &c) = true
c = wrap cause: cause error
errors.As(cause, &c) = true
c = cause error