[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

程式碼範例

  1. package main
  2.  
  3. import (
  4. "fmt"
  5.  
  6. "github.com/pkg/errors"
  7. )
  8.  
  9. func new() error {
  10. return errors.New("new")
  11. }
  12.  
  13. func wrap() error {
  14. return errors.Wrap(new(), "wrap")
  15. }
  16.  
  17. func withMessage() error {
  18. return errors.WithMessage(new(), "message")
  19. }
  20.  
  21. func withStack() error {
  22. return errors.WithStack(new())
  23. }
  24.  
  25. func main() {
  26. eWrap := wrap()
  27. eWithM := withMessage()
  28. eWithS := withStack()
  29.  
  30. fmt.Printf("m: %s\ntype: %s", eWrap, errors.Cause(eWrap))
  31. fmt.Println("\n========stack========")
  32. fmt.Printf("%+v", eWrap)
  33. fmt.Println("\n================================\n")
  34.  
  35. fmt.Printf("m: %s\ntype: %s", eWithM, errors.Cause(eWithM))
  36. fmt.Println("\n========stack========")
  37. fmt.Printf("%+v", eWithM)
  38. fmt.Println("\n================================\n")
  39.  
  40. fmt.Printf("m: %s\ntype: %s", eWithS, errors.Cause(eWithS))
  41. fmt.Println("\n========stack========")
  42. fmt.Printf("%+v", eWithS)
  43. }
  44.  
  45. // output:
  46. // m: wrap: new
  47. // type: new
  48. // ========stack========
  49. // new
  50. // main.new
  51. // c:/Users/zps/Desktop/test.go:10
  52. // main.wrap
  53. // c:/Users/zps/Desktop/test.go:14
  54. // main.main
  55. // c:/Users/zps/Desktop/test.go:26
  56. // runtime.main
  57. // C:/Go/src/runtime/proc.go:201
  58. // runtime.goexit
  59. // C:/Go/src/runtime/asm_amd64.s:1333
  60. // wrap
  61. // main.wrap
  62. // c:/Users/zps/Desktop/test.go:14
  63. // main.main
  64. // c:/Users/zps/Desktop/test.go:26
  65. // runtime.main
  66. // C:/Go/src/runtime/proc.go:201
  67. // runtime.goexit
  68. // C:/Go/src/runtime/asm_amd64.s:1333
  69. // ================================
  70. //
  71. // m: message: new
  72. // type: new
  73. // ========stack========
  74. // new
  75. // main.new
  76. // c:/Users/zps/Desktop/test.go:10
  77. // main.withMessage
  78. // c:/Users/zps/Desktop/test.go:18
  79. // main.main
  80. // c:/Users/zps/Desktop/test.go:27
  81. // runtime.main
  82. // C:/Go/src/runtime/proc.go:201
  83. // runtime.goexit
  84. // C:/Go/src/runtime/asm_amd64.s:1333
  85. // message
  86. // ================================
  87. //
  88. // m: new
  89. // type: new
  90. // ========stack========
  91. // new
  92. // main.new
  93. // c:/Users/zps/Desktop/test.go:10
  94. // main.withStack
  95. // c:/Users/zps/Desktop/test.go:22
  96. // main.main
  97. // c:/Users/zps/Desktop/test.go:28
  98. // runtime.main
  99. // C:/Go/src/runtime/proc.go:201
  100. // runtime.goexit
  101. // C:/Go/src/runtime/asm_amd64.s:1333
  102. // main.withStack
  103. // c:/Users/zps/Desktop/test.go:22
  104. // main.main
  105. // c:/Users/zps/Desktop/test.go:28
  106. // runtime.main
  107. // C:/Go/src/runtime/proc.go:201
  108. // runtime.goexit
  109. // C:/Go/src/runtime/asm_amd64.s:1333

留言