errors.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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. type actionRequired interface {
  12. ActionRequired() bool
  13. }
  14. // Error is an error object with underlying error.
  15. type Error struct {
  16. message string
  17. inner error
  18. actionRequired bool
  19. }
  20. // Error implements error.Error().
  21. func (v *Error) Error() string {
  22. return v.message
  23. }
  24. // Inner implements hasInnerError.Inner()
  25. func (v *Error) Inner() error {
  26. if v.inner == nil {
  27. return nil
  28. }
  29. return v.inner
  30. }
  31. func (v *Error) ActionRequired() bool {
  32. return v.actionRequired
  33. }
  34. // New returns a new error object with message formed from given arguments.
  35. func New(msg ...interface{}) error {
  36. return &Error{
  37. message: serial.Concat(msg...),
  38. }
  39. }
  40. // Base returns an ErrorBuilder based on the given error.
  41. func Base(err error) ErrorBuilder {
  42. return ErrorBuilder{
  43. error: err,
  44. }
  45. }
  46. func Format(format string, values ...interface{}) error {
  47. return New(fmt.Sprintf(format, values...))
  48. }
  49. // Cause returns the root cause of this error.
  50. func Cause(err error) error {
  51. if err == nil {
  52. return nil
  53. }
  54. for {
  55. inner, ok := err.(hasInnerError)
  56. if !ok || inner.Inner() == nil {
  57. break
  58. }
  59. err = inner.Inner()
  60. }
  61. return err
  62. }
  63. func IsActionRequired(err error) bool {
  64. for err != nil {
  65. if ar, ok := err.(actionRequired); ok && ar.ActionRequired() {
  66. return true
  67. }
  68. inner, ok := err.(hasInnerError)
  69. if !ok || inner.Inner() == nil {
  70. break
  71. }
  72. err = inner.Inner()
  73. }
  74. return false
  75. }
  76. type ErrorBuilder struct {
  77. error
  78. actionRequired bool
  79. }
  80. func (v ErrorBuilder) RequireUserAction() ErrorBuilder {
  81. v.actionRequired = true
  82. return v
  83. }
  84. // Message returns an error object with given message and base error.
  85. func (v ErrorBuilder) Message(msg ...interface{}) error {
  86. if v.error == nil {
  87. return nil
  88. }
  89. return &Error{
  90. message: serial.Concat(msg...) + " > " + v.error.Error(),
  91. inner: v.error,
  92. actionRequired: v.actionRequired,
  93. }
  94. }
  95. // Format returns an errors object with given message format and base error.
  96. func (v ErrorBuilder) Format(format string, values ...interface{}) error {
  97. if v.error == nil {
  98. return nil
  99. }
  100. return &Error{
  101. message: fmt.Sprintf(format, values...) + " > " + v.error.Error(),
  102. inner: v.error,
  103. actionRequired: v.actionRequired,
  104. }
  105. }