error.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. package valid
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "sort"
  8. "strings"
  9. "text/template"
  10. )
  11. var (
  12. // ErrStructPointer is the error that a struct being validated is not specified as a pointer.
  13. ErrStructPointer = errors.New("only a pointer to a struct can be validated")
  14. )
  15. // ErrorTag is the struct tag name used to customize the error field name for a struct field.
  16. var ErrorTag = "json"
  17. // Error interface represents an validation error
  18. type Error interface {
  19. Error() string
  20. Code() string
  21. Message() string
  22. SetMessage(string) Error
  23. Params() map[string]interface{}
  24. SetParams(map[string]interface{}) Error
  25. }
  26. // InternalError represents an error that should NOT be treated as a validation error.
  27. type InternalError interface {
  28. error
  29. InternalError() error
  30. }
  31. type internalError struct {
  32. error
  33. }
  34. // NewInternalError wraps a given error into an InternalError.
  35. func NewInternalError(err error) InternalError {
  36. return internalError{error: err}
  37. }
  38. // InternalError returns the actual error that it wraps around.
  39. func (e internalError) InternalError() error {
  40. return e.error
  41. }
  42. // Errors represents the validation errors that are indexed by struct field names, map or slice keys.
  43. // values are Error or Errors (for map, slice and array error value is Errors).
  44. type Errors map[string]error
  45. // Error returns the error string of Errors.
  46. func (es Errors) Error() string {
  47. if len(es) == 0 {
  48. return ""
  49. }
  50. keys := make([]string, len(es))
  51. i := 0
  52. for key := range es {
  53. keys[i] = key
  54. i++
  55. }
  56. sort.Strings(keys)
  57. var s strings.Builder
  58. for i, key := range keys {
  59. if i > 0 {
  60. s.WriteString("; ")
  61. }
  62. if errs, ok := es[key].(Errors); ok {
  63. _, _ = fmt.Fprintf(&s, "%v: (%v)", key, errs)
  64. } else {
  65. _, _ = fmt.Fprintf(&s, "%v: %v", key, es[key].Error())
  66. }
  67. }
  68. s.WriteString(".")
  69. return s.String()
  70. }
  71. // MarshalJSON converts the Errors into a valid JSON.
  72. func (es Errors) MarshalJSON() ([]byte, error) {
  73. errs := map[string]interface{}{}
  74. for key, err := range es {
  75. if ms, ok := err.(json.Marshaler); ok {
  76. errs[key] = ms
  77. } else {
  78. errs[key] = err.Error()
  79. }
  80. }
  81. return json.Marshal(errs)
  82. }
  83. // Filter removes all nils from Errors and returns back the updated Errors as an error.
  84. // If the length of Errors becomes 0, it will return nil.
  85. func (es Errors) Filter() error {
  86. for key, value := range es {
  87. if value == nil {
  88. delete(es, key)
  89. }
  90. }
  91. if len(es) == 0 {
  92. return nil
  93. }
  94. return es
  95. }
  96. // NewError create new validation error.
  97. func NewError(code, message string) Error {
  98. return ErrorObject{
  99. code: code,
  100. message: message,
  101. }
  102. }
  103. // Assert that our ErrorObject implements the Error interface.
  104. var _ Error = ErrorObject{}
  105. // ErrorObject is the default validation error
  106. // that implements the Error interface.
  107. type ErrorObject struct {
  108. code string
  109. message string
  110. params map[string]interface{}
  111. }
  112. // SetCode set the error's translation code.
  113. func (e ErrorObject) SetCode(code string) Error {
  114. e.code = code
  115. return e
  116. }
  117. // Code get the error's translation code.
  118. func (e ErrorObject) Code() string {
  119. return e.code
  120. }
  121. // SetParams set the error's params.
  122. func (e ErrorObject) SetParams(params map[string]interface{}) Error {
  123. e.params = params
  124. return e
  125. }
  126. // AddParam add parameter to the error's parameters.
  127. func (e ErrorObject) AddParam(name string, value interface{}) Error {
  128. if e.params == nil {
  129. e.params = make(map[string]interface{})
  130. }
  131. e.params[name] = value
  132. return e
  133. }
  134. // Params returns the error's params.
  135. func (e ErrorObject) Params() map[string]interface{} {
  136. return e.params
  137. }
  138. // SetMessage set the error's message.
  139. func (e ErrorObject) SetMessage(message string) Error {
  140. e.message = message
  141. return e
  142. }
  143. // Message return the error's message.
  144. func (e ErrorObject) Message() string {
  145. return e.message
  146. }
  147. // Error returns the error message.
  148. func (e ErrorObject) Error() string {
  149. if len(e.params) == 0 {
  150. return e.message
  151. }
  152. res := bytes.Buffer{}
  153. _ = template.Must(template.New("err").Parse(e.message)).Execute(&res, e.params)
  154. return res.String()
  155. }
  156. // ErrFieldPointer is the error that a field is not specified as a pointer.
  157. type ErrFieldPointer int
  158. // Error returns the error string of ErrFieldPointer.
  159. func (e ErrFieldPointer) Error() string {
  160. return fmt.Sprintf("field #%v must be specified as a pointer", int(e))
  161. }
  162. // ErrFieldNotFound is the error that a field cannot be found in the struct.
  163. type ErrFieldNotFound int
  164. // Error returns the error string of ErrFieldNotFound.
  165. func (e ErrFieldNotFound) Error() string {
  166. return fmt.Sprintf("field #%v cannot be found in the struct", int(e))
  167. }