[Go] 如何處理 error

程式語言:Go
Package:
github.com/pkg/errors
官方文件
官方 GitHub

功能:處理 error

建議做法

使用 errors 添加額外的上下文信息到原始錯誤信息
當錯誤最終由 main 函數處理時,錯誤信息應提供清晰的從原因到後果的因果鏈
就像美國宇航局事故調査時做的那樣:
genesis: crashed: no parachute: G-switch failed: bad relay orientation
由於錯誤信息經常是以鏈式組合在一起的,所以錯誤信息中應避免大寫和換行符
  • errors
    • func Cause(err error) error
      • 回傳最底層的 error,可用來判斷,如下兩種方式
        switch err.(type)
        switch err
        
    • func New(message string) error
      func Errorf(format string, args ...interface{}) error
      • 新建 error,並記錄當前的 stack trace
    • func WithMessage(err error, message string) error
      func WithMessagef(err error, format string, args ...interface{}) error
      • 添加 新的訊息,但不添加 stack trace
    • func WithStack(err error) error
      • 添加 當前的 stack trace,但不添加訊息
    • func Wrap(err error, message string) error
      func Wrapf(err error, format string, args ...interface{}) error
      • 添加 新的訊息 與 當前的 stack trace

程式碼範例

package main

import (
 "fmt"

 "github.com/pkg/errors"
)

func new() error {
 return errors.New("new")
}

func wrap() error {
 return errors.Wrap(new(), "wrap")
}

func withMessage() error {
 return errors.WithMessage(new(), "message")
}

func withStack() error {
 return errors.WithStack(new())
}

func main() {
 eWrap := wrap()
 eWithM := withMessage()
 eWithS := withStack()

 fmt.Printf("m: %s\ntype: %s", eWrap, errors.Cause(eWrap))
 fmt.Println("\n========stack========")
 fmt.Printf("%+v", eWrap)
 fmt.Println("\n================================\n")

 fmt.Printf("m: %s\ntype: %s", eWithM, errors.Cause(eWithM))
 fmt.Println("\n========stack========")
 fmt.Printf("%+v", eWithM)
 fmt.Println("\n================================\n")

 fmt.Printf("m: %s\ntype: %s", eWithS, errors.Cause(eWithS))
 fmt.Println("\n========stack========")
 fmt.Printf("%+v", eWithS)
}

// output:
// m: wrap: new
// type: new
// ========stack========
// new
// main.new
//  c:/Users/zps/Desktop/test.go:10
// main.wrap
//  c:/Users/zps/Desktop/test.go:14
// main.main
//  c:/Users/zps/Desktop/test.go:26
// runtime.main
//  C:/Go/src/runtime/proc.go:201
// runtime.goexit
//  C:/Go/src/runtime/asm_amd64.s:1333
// wrap
// main.wrap
//  c:/Users/zps/Desktop/test.go:14
// main.main
//  c:/Users/zps/Desktop/test.go:26
// runtime.main
//  C:/Go/src/runtime/proc.go:201
// runtime.goexit
//  C:/Go/src/runtime/asm_amd64.s:1333
// ================================
//
// m: message: new
// type: new
// ========stack========
// new
// main.new
//  c:/Users/zps/Desktop/test.go:10
// main.withMessage
//  c:/Users/zps/Desktop/test.go:18
// main.main
//  c:/Users/zps/Desktop/test.go:27
// runtime.main
//  C:/Go/src/runtime/proc.go:201
// runtime.goexit
//  C:/Go/src/runtime/asm_amd64.s:1333
// message
// ================================
//
// m: new
// type: new
// ========stack========
// new
// main.new
//  c:/Users/zps/Desktop/test.go:10
// main.withStack
//  c:/Users/zps/Desktop/test.go:22
// main.main
//  c:/Users/zps/Desktop/test.go:28
// runtime.main
//  C:/Go/src/runtime/proc.go:201
// runtime.goexit
//  C:/Go/src/runtime/asm_amd64.s:1333
// main.withStack
//  c:/Users/zps/Desktop/test.go:22
// main.main
//  c:/Users/zps/Desktop/test.go:28
// runtime.main
//  C:/Go/src/runtime/proc.go:201
// runtime.goexit
//  C:/Go/src/runtime/asm_amd64.s:1333

留言