Validate validates a struct based on struct tags and other custom rules registered
(v any)
| 10 | |
| 11 | // Validate validates a struct based on struct tags and other custom rules registered |
| 12 | func Validate(v any) error { |
| 13 | err := validate.Struct(v) |
| 14 | if err == nil { |
| 15 | return nil |
| 16 | } |
| 17 | |
| 18 | // Attempt to unwrap the first field error. |
| 19 | var fe validator.FieldError |
| 20 | var verrs validator.ValidationErrors |
| 21 | if errors.As(err, &verrs) && len(verrs) > 0 { |
| 22 | fe = verrs[0] |
| 23 | } |
| 24 | |
| 25 | // If the error is not a field error, return it as is. |
| 26 | if fe == nil { |
| 27 | return NewValidationError(err.Error()) |
| 28 | } |
| 29 | |
| 30 | // Custom error messages |
| 31 | if fe.Tag() == "slug" { |
| 32 | return NewValidationError(fmt.Sprintf("Validation failed for field '%s': must use only letters, numbers, underscores and dashes", fe.Field())) |
| 33 | } |
| 34 | if fe.Tag() == "required" { |
| 35 | return NewValidationError(fmt.Sprintf("Validation failed for field '%s': must be set", fe.Field())) |
| 36 | } |
| 37 | if fe.Tag() == "min" { |
| 38 | return NewValidationError(fmt.Sprintf("Validation failed for field '%s': must be at least %s characters", fe.Field(), fe.Param())) |
| 39 | } |
| 40 | if fe.Tag() == "max" { |
| 41 | return NewValidationError(fmt.Sprintf("Validation failed for field '%s': must be at most %s characters", fe.Field(), fe.Param())) |
| 42 | } |
| 43 | |
| 44 | // Fallback to a generic error message. |
| 45 | // Example: "Validation rule 'len=10' failed for field 'Name' ('InsertOptions.Name')" |
| 46 | var param string |
| 47 | if fe.Param() != "" { |
| 48 | param = fmt.Sprintf("=%s", fe.Param()) |
| 49 | } |
| 50 | return NewValidationError(fmt.Sprintf("Validation rule '%s%s' failed for field '%s' ('%s')", fe.Tag(), param, fe.Field(), fe.StructNamespace())) |
| 51 | } |
| 52 | |
| 53 | // validate caches parsed validation rules |
| 54 | var validate *validator.Validate |