All Articles

Go1.13でのエラーハンドリング

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