error.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // Copyright 2016 Qiang Xue. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package validation
  5. import (
  6. "encoding/json"
  7. "fmt"
  8. "sort"
  9. )
  10. type (
  11. // Errors represents the validation errors that are indexed by struct field names, map or slice keys.
  12. Errors map[string]error
  13. // InternalError represents an error that should NOT be treated as a validation error.
  14. InternalError interface {
  15. error
  16. InternalError() error
  17. }
  18. internalError struct {
  19. error
  20. }
  21. )
  22. // NewInternalError wraps a given error into an InternalError.
  23. func NewInternalError(err error) InternalError {
  24. return &internalError{error: err}
  25. }
  26. // InternalError returns the actual error that it wraps around.
  27. func (e *internalError) InternalError() error {
  28. return e.error
  29. }
  30. // Error returns the error string of Errors.
  31. func (es Errors) Error() string {
  32. if len(es) == 0 {
  33. return ""
  34. }
  35. keys := []string{}
  36. for key := range es {
  37. keys = append(keys, key)
  38. }
  39. sort.Strings(keys)
  40. s := ""
  41. for i, key := range keys {
  42. if i > 0 {
  43. s += "; "
  44. }
  45. if errs, ok := es[key].(Errors); ok {
  46. s += fmt.Sprintf("%v: (%v)", key, errs)
  47. } else {
  48. s += fmt.Sprintf("%v: %v", key, es[key].Error())
  49. }
  50. }
  51. return s + "."
  52. }
  53. // MarshalJSON converts the Errors into a valid JSON.
  54. func (es Errors) MarshalJSON() ([]byte, error) {
  55. errs := map[string]interface{}{}
  56. for key, err := range es {
  57. if ms, ok := err.(json.Marshaler); ok {
  58. errs[key] = ms
  59. } else {
  60. errs[key] = err.Error()
  61. }
  62. }
  63. return json.Marshal(errs)
  64. }
  65. // Filter removes all nils from Errors and returns back the updated Errors as an error.
  66. // If the length of Errors becomes 0, it will return nil.
  67. func (es Errors) Filter() error {
  68. for key, value := range es {
  69. if value == nil {
  70. delete(es, key)
  71. }
  72. }
  73. if len(es) == 0 {
  74. return nil
  75. }
  76. return es
  77. }