errors.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Package errors is a drop-in replacement for Golang lib 'errors'.
  2. package errors
  3. import (
  4. "fmt"
  5. "v2ray.com/core/common/serial"
  6. )
  7. type hasInnerError interface {
  8. // Inner returns the underlying error of this one.
  9. Inner() error
  10. }
  11. // Error is an error object with underlying error.
  12. type Error struct {
  13. message string
  14. inner error
  15. }
  16. // Error implements error.Error().
  17. func (v *Error) Error() string {
  18. return v.message
  19. }
  20. // Inner implements hasInnerError.Inner()
  21. func (v *Error) Inner() error {
  22. if v.inner == nil {
  23. return nil
  24. }
  25. return v.inner
  26. }
  27. // New returns a new error object with message formed from given arguments.
  28. func New(msg ...interface{}) error {
  29. return &Error{
  30. message: serial.Concat(msg...),
  31. }
  32. }
  33. // Base returns an ErrorBuilder based on the given error.
  34. func Base(err error) ErrorBuilder {
  35. return ErrorBuilder{
  36. error: err,
  37. }
  38. }
  39. func Format(format string, values ...interface{}) error {
  40. return New(fmt.Sprintf(format, values...))
  41. }
  42. // Cause returns the root cause of this error.
  43. func Cause(err error) error {
  44. if err == nil {
  45. return nil
  46. }
  47. for {
  48. inner, ok := err.(hasInnerError)
  49. if !ok {
  50. break
  51. }
  52. if inner.Inner() == nil {
  53. break
  54. }
  55. err = inner.Inner()
  56. }
  57. return err
  58. }
  59. type ErrorBuilder struct {
  60. error
  61. }
  62. // Message returns an error object with given message and base error.
  63. func (v ErrorBuilder) Message(msg ...interface{}) error {
  64. if v.error == nil {
  65. return nil
  66. }
  67. return &Error{
  68. message: serial.Concat(msg...) + " > " + v.error.Error(),
  69. inner: v.error,
  70. }
  71. }
  72. // Format returns an errors object with given message format and base error.
  73. func (v ErrorBuilder) Format(format string, values ...interface{}) error {
  74. if v.error == nil {
  75. return nil
  76. }
  77. return &Error{
  78. message: fmt.Sprintf(format, values...) + " > " + v.error.Error(),
  79. inner: v.error,
  80. }
  81. }