
errors.New("error message")
自定義struct,建立方法符合 interface error( Error() string)
<aside> 💡 可以用指標(Point)。重複使用避免浪費~
</aside>
type CustomErr struct {
Msg string
}
func (c CustomErr) Error() string {
return fmt.Sprintf("Custom Error with struct. Msg: %s\\n", c.Msg)
}
func NewCustomErr(msg string) error {
return &CustomErr{msg}
}
包裝底層錯誤,增加上下文訊息
fmt.Errorf("bar failed: %w", foo()) → 包裝(嵌套)錯誤errors.Unwrap → 解開嵌套的錯誤,取出最底層的錯誤errors.Is(errA, errB) bool → 判斷錯誤是否相同,如果是errA是嵌套的錯誤,會再往下層尋找erros.As(errA, targetB interface{}) bool → 判斷錯誤是否相同外,會將從嵌套錯誤中尋找到的error指派到targetB
testErr := errors.New("Test Error.")
wrappedErr := fmt.Errorf("bar failed: %w", testErr)
fmt.Printf("wrappedErr: [%v]\\n", wrappedErr)
errFromUnwrap := errors.Unwrap(wrappedErr)
fmt.Printf("wrappedErr is testErr: %v\\n", errors.Is(wrappedErr, testErr))
fmt.Printf("errFromUnwrap is testErr: %v\\n", errors.Is(errFromUnwrap, testErr))
customErr := NewCustomErr("Custom Error.")
var targetErr *CustomErr
wrappedErrWithCustomErr := fmt.Errorf("Wrapped Custom Error: [%w]", customErr)
isCustomErr := errors.As(wrappedErrWithCustomErr, &targetErr)
fmt.Printf("\\nisCustomErr: %v\\nCustomErr.Msg: %v\\n", isCustomErr, targetErr.Msg)
// output
// wrappedErr: [bar failed: Test Error.]
// wrappedErr is testErr: true
// errFromUnwrap is testErr: true
// isCustomErr: true
// CustomErr.Msg: Custom Error.
相較於原生的erros, github.com/pkg/errors 能夠包含堆疊資訊,更方便於除錯
包裝(嵌套)錯誤
<aside> 💡 無論是Wrap, WithMessage, WithStack,當傳入的error為nil時,都會返回nil,不需要在使用前做nil的判斷
</aside>
WithMessage(err error, message string) error → 只有訊息WithStack(err error) error → 只有調用的過程,經過了哪些函式(行數)Wrap(err error, message string) error → 除了訊息外,還有附加調用的過程,經過了哪些函式(行數)