errors.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. // Package errors provides simple error handling primitives.
  2. //
  3. // The traditional error handling idiom in Go is roughly akin to
  4. //
  5. // if err != nil {
  6. // return err
  7. // }
  8. //
  9. // which applied recursively up the call stack results in error reports
  10. // without context or debugging information. The errors package allows
  11. // programmers to add context to the failure path in their code in a way
  12. // that does not destroy the original value of the error.
  13. //
  14. // Adding context to an error
  15. //
  16. // The errors.Wrap function returns a new error that adds context to the
  17. // original error by recording a stack trace at the point Wrap is called,
  18. // and the supplied message. For example
  19. //
  20. // _, err := ioutil.ReadAll(r)
  21. // if err != nil {
  22. // return errors.Wrap(err, "read failed")
  23. // }
  24. //
  25. // If additional control is required the errors.WithStack and errors.WithMessage
  26. // functions destructure errors.Wrap into its component operations of annotating
  27. // an error with a stack trace and an a message, respectively.
  28. //
  29. // Retrieving the cause of an error
  30. //
  31. // Using errors.Wrap constructs a stack of errors, adding context to the
  32. // preceding error. Depending on the nature of the error it may be necessary
  33. // to reverse the operation of errors.Wrap to retrieve the original error
  34. // for inspection. Any error value which implements this interface
  35. //
  36. // type causer interface {
  37. // Cause() error
  38. // }
  39. //
  40. // can be inspected by errors.Cause. errors.Cause will recursively retrieve
  41. // the topmost error which does not implement causer, which is assumed to be
  42. // the original cause. For example:
  43. //
  44. // switch err := errors.Cause(err).(type) {
  45. // case *MyError:
  46. // // handle specifically
  47. // default:
  48. // // unknown error
  49. // }
  50. //
  51. // causer interface is not exported by this package, but is considered a part
  52. // of stable public API.
  53. //
  54. // Formatted printing of errors
  55. //
  56. // All error values returned from this package implement fmt.Formatter and can
  57. // be formatted by the fmt package. The following verbs are supported
  58. //
  59. // %s print the error. If the error has a Cause it will be
  60. // printed recursively
  61. // %v see %s
  62. // %+v extended format. Each Frame of the error's StackTrace will
  63. // be printed in detail.
  64. //
  65. // Retrieving the stack trace of an error or wrapper
  66. //
  67. // New, Errorf, Wrap, and Wrapf record a stack trace at the point they are
  68. // invoked. This information can be retrieved with the following interface.
  69. //
  70. // type stackTracer interface {
  71. // StackTrace() errors.StackTrace
  72. // }
  73. //
  74. // Where errors.StackTrace is defined as
  75. //
  76. // type StackTrace []Frame
  77. //
  78. // The Frame type represents a call site in the stack trace. Frame supports
  79. // the fmt.Formatter interface that can be used for printing information about
  80. // the stack trace of this error. For example:
  81. //
  82. // if err, ok := err.(stackTracer); ok {
  83. // for _, f := range err.StackTrace() {
  84. // fmt.Printf("%+s:%d", f)
  85. // }
  86. // }
  87. //
  88. // stackTracer interface is not exported by this package, but is considered a part
  89. // of stable public API.
  90. //
  91. // See the documentation for Frame.Format for more details.
  92. package errors
  93. import (
  94. "fmt"
  95. "io"
  96. )
  97. // New returns an error with the supplied message.
  98. // New also records the stack trace at the point it was called.
  99. func New(message string) error {
  100. return &fundamental{
  101. msg: message,
  102. stack: callers(),
  103. }
  104. }
  105. // Errorf formats according to a format specifier and returns the string
  106. // as a value that satisfies error.
  107. // Errorf also records the stack trace at the point it was called.
  108. func Errorf(format string, args ...interface{}) error {
  109. return &fundamental{
  110. msg: fmt.Sprintf(format, args...),
  111. stack: callers(),
  112. }
  113. }
  114. // fundamental is an error that has a message and a stack, but no caller.
  115. type fundamental struct {
  116. msg string
  117. *stack
  118. }
  119. func (f *fundamental) Error() string { return f.msg }
  120. func (f *fundamental) Format(s fmt.State, verb rune) {
  121. switch verb {
  122. case 'v':
  123. if s.Flag('+') {
  124. io.WriteString(s, f.msg)
  125. f.stack.Format(s, verb)
  126. return
  127. }
  128. fallthrough
  129. case 's':
  130. io.WriteString(s, f.msg)
  131. case 'q':
  132. fmt.Fprintf(s, "%q", f.msg)
  133. }
  134. }
  135. // WithStack annotates err with a stack trace at the point WithStack was called.
  136. // If err is nil, WithStack returns nil.
  137. func WithStack(err error) error {
  138. if err == nil {
  139. return nil
  140. }
  141. return &withStack{
  142. err,
  143. callers(),
  144. }
  145. }
  146. type withStack struct {
  147. error
  148. *stack
  149. }
  150. func (w *withStack) Cause() error { return w.error }
  151. func (w *withStack) Format(s fmt.State, verb rune) {
  152. switch verb {
  153. case 'v':
  154. if s.Flag('+') {
  155. fmt.Fprintf(s, "%+v", w.Cause())
  156. w.stack.Format(s, verb)
  157. return
  158. }
  159. fallthrough
  160. case 's':
  161. io.WriteString(s, w.Error())
  162. case 'q':
  163. fmt.Fprintf(s, "%q", w.Error())
  164. }
  165. }
  166. // Wrap returns an error annotating err with a stack trace
  167. // at the point Wrap is called, and the supplied message.
  168. // If err is nil, Wrap returns nil.
  169. func Wrap(err error, message string) error {
  170. if err == nil {
  171. return nil
  172. }
  173. err = &withMessage{
  174. cause: err,
  175. msg: message,
  176. }
  177. return &withStack{
  178. err,
  179. callers(),
  180. }
  181. }
  182. // Wrapf returns an error annotating err with a stack trace
  183. // at the point Wrapf is call, and the format specifier.
  184. // If err is nil, Wrapf returns nil.
  185. func Wrapf(err error, format string, args ...interface{}) error {
  186. if err == nil {
  187. return nil
  188. }
  189. err = &withMessage{
  190. cause: err,
  191. msg: fmt.Sprintf(format, args...),
  192. }
  193. return &withStack{
  194. err,
  195. callers(),
  196. }
  197. }
  198. // WithMessage annotates err with a new message.
  199. // If err is nil, WithMessage returns nil.
  200. func WithMessage(err error, message string) error {
  201. if err == nil {
  202. return nil
  203. }
  204. return &withMessage{
  205. cause: err,
  206. msg: message,
  207. }
  208. }
  209. type withMessage struct {
  210. cause error
  211. msg string
  212. }
  213. func (w *withMessage) Error() string { return w.msg + ": " + w.cause.Error() }
  214. func (w *withMessage) Cause() error { return w.cause }
  215. func (w *withMessage) Format(s fmt.State, verb rune) {
  216. switch verb {
  217. case 'v':
  218. if s.Flag('+') {
  219. fmt.Fprintf(s, "%+v\n", w.Cause())
  220. io.WriteString(s, w.msg)
  221. return
  222. }
  223. fallthrough
  224. case 's', 'q':
  225. io.WriteString(s, w.Error())
  226. }
  227. }
  228. // Cause returns the underlying cause of the error, if possible.
  229. // An error value has a cause if it implements the following
  230. // interface:
  231. //
  232. // type causer interface {
  233. // Cause() error
  234. // }
  235. //
  236. // If the error does not implement Cause, the original error will
  237. // be returned. If the error is nil, nil will be returned without further
  238. // investigation.
  239. func Cause(err error) error {
  240. type causer interface {
  241. Cause() error
  242. }
  243. for err != nil {
  244. cause, ok := err.(causer)
  245. if !ok {
  246. break
  247. }
  248. err = cause.Cause()
  249. }
  250. return err
  251. }