package validator import ( "fmt" "strings" "github.com/go-kratos/kratos/v2/errors" ) // ValidationError 验证错误 type ValidationError struct { FieldPath string // 字段路径 如 "user.email" RuleID string // 规则ID Message string // 错误消息(中文) MessageEN string // 错误消息(英文) Value interface{} // 失败的值 Metadata map[string]string // 附加信息 } // Error 实现 error 接口 func (e *ValidationError) Error() string { if e.FieldPath != "" { return fmt.Sprintf("%s: %s", e.FieldPath, e.Message) } return e.Message } // ValidationErrors 多个验证错误的集合 type ValidationErrors struct { Errors []*ValidationError // 错误列表 Warnings []*ValidationError // 警告列表(非阻塞) } // Error 实现 error 接口 func (e *ValidationErrors) Error() string { if len(e.Errors) == 0 { return "" } var messages []string for _, err := range e.Errors { messages = append(messages, err.Error()) } return strings.Join(messages, "; ") } // Add 添加错误 func (e *ValidationErrors) Add(err *ValidationError) { if e.Errors == nil { e.Errors = make([]*ValidationError, 0) } e.Errors = append(e.Errors, err) } // AddWarning 添加警告 func (e *ValidationErrors) AddWarning(err *ValidationError) { if e.Warnings == nil { e.Warnings = make([]*ValidationError, 0) } e.Warnings = append(e.Warnings, err) } // HasErrors 是否有错误 func (e *ValidationErrors) HasErrors() bool { return len(e.Errors) > 0 } // IsEmpty 是否为空 func (e *ValidationErrors) IsEmpty() bool { return len(e.Errors) == 0 && len(e.Warnings) == 0 } // Count 错误数量 func (e *ValidationErrors) Count() int { return len(e.Errors) } // ToKratosError 转换为 Kratos 错误 func (e *ValidationErrors) ToKratosError() error { if !e.HasErrors() { return nil } // 构建详细的错误消息 var messages []string for _, err := range e.Errors { messages = append(messages, err.Error()) } // 使用 Kratos 的 BadRequest 错误 kratosErr := errors.BadRequest( "VALIDATION_FAILED", strings.Join(messages, "; "), ) // 添加错误元数据 metadata := make(map[string]string) for i, err := range e.Errors { prefix := fmt.Sprintf("error_%d", i) metadata[prefix+"_field"] = err.FieldPath metadata[prefix+"_rule"] = err.RuleID metadata[prefix+"_message"] = err.Message } return kratosErr.WithMetadata(metadata) } // NewValidationError 创建验证错误 func NewValidationError(fieldPath, ruleID, message string) *ValidationError { return &ValidationError{ FieldPath: fieldPath, RuleID: ruleID, Message: message, } } // NewValidationErrorWithValue 创建带值的验证错误 func NewValidationErrorWithValue(fieldPath, ruleID, message string, value interface{}) *ValidationError { return &ValidationError{ FieldPath: fieldPath, RuleID: ruleID, Message: message, Value: value, } } // 预定义错误代码 const ( ErrCodeInvalidValue = "INVALID_VALUE" ErrCodeRequired = "REQUIRED_FIELD" ErrCodeInvalidFormat = "INVALID_FORMAT" ErrCodeOutOfRange = "OUT_OF_RANGE" ErrCodeInvalidLength = "INVALID_LENGTH" ErrCodeInvalidPattern = "INVALID_PATTERN" ErrCodeCELExecution = "CEL_EXECUTION_ERROR" )