errors.go 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. package misc
  2. import (
  3. "fmt"
  4. "golang.org/x/xerrors"
  5. )
  6. type wrapError struct {
  7. message string
  8. next error
  9. frame xerrors.Frame
  10. }
  11. func (e *wrapError) Unwrap() error {
  12. return e.next
  13. }
  14. func (e *wrapError) Error() string {
  15. if e.next == nil {
  16. return e.message
  17. }
  18. return fmt.Sprintf("%s: %v", e.message, e.next)
  19. }
  20. func (e *wrapError) Format(f fmt.State, c rune) {
  21. xerrors.FormatError(e, f, c)
  22. }
  23. func (e *wrapError) FormatError(p xerrors.Printer) error {
  24. p.Print(e.message)
  25. if p.Detail() {
  26. e.frame.Format(p)
  27. }
  28. return e.next
  29. }
  30. func wrap(err error, message string, skip int) error {
  31. if err == nil {
  32. return nil
  33. }
  34. return &wrapError{
  35. message: message,
  36. next: err,
  37. frame: xerrors.Caller(skip),
  38. }
  39. }
  40. // Wrap returns a error annotating `err` with `message` and the caller's frame.
  41. // Wrap returns nil if `err` is nil.
  42. func ErrorWrap(err error, message string) error {
  43. return wrap(err, message, 2)
  44. }
  45. // Wrapf returns a error annotating `err` with `message` formatted and the caller's frame.
  46. func ErrorWrapf(err error, message string, args ...interface{}) error {
  47. return wrap(err, fmt.Sprintf(message, args...), 2)
  48. }