errors.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. package validator
  2. import (
  3. "fmt"
  4. "strings"
  5. "github.com/go-kratos/kratos/v2/errors"
  6. )
  7. // ValidationError 验证错误
  8. type ValidationError struct {
  9. FieldPath string // 字段路径 如 "user.email"
  10. RuleID string // 规则ID
  11. Message string // 错误消息(中文)
  12. MessageEN string // 错误消息(英文)
  13. Value interface{} // 失败的值
  14. Metadata map[string]string // 附加信息
  15. }
  16. // Error 实现 error 接口
  17. func (e *ValidationError) Error() string {
  18. //if e.FieldPath != "" {
  19. // return fmt.Sprintf("%s: %s", e.FieldPath, e.Message)
  20. //}
  21. return e.Message
  22. }
  23. // ValidationErrors 多个验证错误的集合
  24. type ValidationErrors struct {
  25. Errors []*ValidationError // 错误列表
  26. Warnings []*ValidationError // 警告列表(非阻塞)
  27. }
  28. // Error 实现 error 接口
  29. func (e *ValidationErrors) Error() string {
  30. if len(e.Errors) == 0 {
  31. return ""
  32. }
  33. var messages []string
  34. for _, err := range e.Errors {
  35. messages = append(messages, err.Error())
  36. }
  37. return strings.Join(messages, "; ")
  38. }
  39. // Add 添加错误
  40. func (e *ValidationErrors) Add(err *ValidationError) {
  41. if e.Errors == nil {
  42. e.Errors = make([]*ValidationError, 0)
  43. }
  44. e.Errors = append(e.Errors, err)
  45. }
  46. // AddWarning 添加警告
  47. func (e *ValidationErrors) AddWarning(err *ValidationError) {
  48. if e.Warnings == nil {
  49. e.Warnings = make([]*ValidationError, 0)
  50. }
  51. e.Warnings = append(e.Warnings, err)
  52. }
  53. // HasErrors 是否有错误
  54. func (e *ValidationErrors) HasErrors() bool {
  55. return len(e.Errors) > 0
  56. }
  57. // IsEmpty 是否为空
  58. func (e *ValidationErrors) IsEmpty() bool {
  59. return len(e.Errors) == 0 && len(e.Warnings) == 0
  60. }
  61. // Count 错误数量
  62. func (e *ValidationErrors) Count() int {
  63. return len(e.Errors)
  64. }
  65. // ToKratosError 转换为 Kratos 错误
  66. func (e *ValidationErrors) ToKratosError() error {
  67. if !e.HasErrors() {
  68. return nil
  69. }
  70. // 构建详细的错误消息
  71. var messages []string
  72. for _, err := range e.Errors {
  73. messages = append(messages, err.Error())
  74. }
  75. // 使用 Kratos 的 BadRequest 错误
  76. kratosErr := errors.BadRequest(
  77. "VALIDATION_FAILED",
  78. strings.Join(messages, "; "),
  79. )
  80. // 添加错误元数据
  81. metadata := make(map[string]string)
  82. for i, err := range e.Errors {
  83. prefix := fmt.Sprintf("error_%d", i)
  84. metadata[prefix+"_field"] = err.FieldPath
  85. metadata[prefix+"_rule"] = err.RuleID
  86. metadata[prefix+"_message"] = err.Message
  87. }
  88. return kratosErr.WithMetadata(metadata)
  89. }
  90. // NewValidationError 创建验证错误
  91. func NewValidationError(fieldPath, ruleID, message string) *ValidationError {
  92. return &ValidationError{
  93. FieldPath: fieldPath,
  94. RuleID: ruleID,
  95. Message: message,
  96. }
  97. }
  98. // NewValidationErrorWithValue 创建带值的验证错误
  99. func NewValidationErrorWithValue(fieldPath, ruleID, message string, value interface{}) *ValidationError {
  100. return &ValidationError{
  101. FieldPath: fieldPath,
  102. RuleID: ruleID,
  103. Message: message,
  104. Value: value,
  105. }
  106. }
  107. // 预定义错误代码
  108. const (
  109. ErrCodeInvalidValue = "INVALID_VALUE"
  110. ErrCodeRequired = "REQUIRED_FIELD"
  111. ErrCodeInvalidFormat = "INVALID_FORMAT"
  112. ErrCodeOutOfRange = "OUT_OF_RANGE"
  113. ErrCodeInvalidLength = "INVALID_LENGTH"
  114. ErrCodeInvalidPattern = "INVALID_PATTERN"
  115. ErrCodeCELExecution = "CEL_EXECUTION_ERROR"
  116. )