validator
validator copied to clipboard
Custom rule function `FieldLevel.FieldName()` return empty string on `Validate.ValidateMap()`
- [x] I have looked at the documentation here first?
- [x] I have looked at the examples provided that may showcase my question here?
Package version eg. v9, v10:
v10
Issue, Question or Enhancement:
Custom rule FieldLevel.FieldName() return empty string on Validate.ValidateMap()
Code sample, to showcase or reproduce:
main.go
package main
import (
"fmt"
"reflect"
"github.com/go-playground/validator/v10"
)
func main() {
validate := validator.New()
validate.RegisterTagNameFunc(func(field reflect.StructField) string {
fmt.Println("TagNameFunc")
return "test"
})
validate.RegisterValidation("presented", func(fl validator.FieldLevel) bool {
fmt.Println("presented")
fmt.Println("fl.FieldName()", fl.FieldName())
return false
}, true)
data := map[string]interface{}{
"field": "nil",
}
rule := map[string]interface{}{
"field": "presented",
}
result := validate.ValidateMap(data, rule)
fmt.Println("result", result)
err := result["field"]
fmt.Println(reflect.TypeOf(err))
fmt.Println(err)
}
output:
presented
fl.FieldName()
result map[field:Key: '' Error:Field validation for '' failed on the 'presented' tag]
validator.ValidationErrors
Key: '' Error:Field validation for '' failed on the 'presented' tag
Expected
FieldLevel.FieldName() will return string "field" instead of empty string "".
It's also happened to me.
In my case it's happened when I'm trying to validate map using ValidateMap and then trying to cast the result into validation.ValidationErrors.
The error.Field() and error.StructField() always returning empty string.
Probably this is a bug when validating a map, the key (field name) is not returned back.
I am also having this issue: I use ValidateMap but cannot get the field name
I am using this workaround:
// Get all validation results
validationResults := V.ValidateMap(*in, params.validationRules)
// Check if there are validation errors
allErrors := make([]error, 0)
if len(validationResults) > 0 {
for property, v := range validationResults {
if validationErr, ok := v.(validator.ValidationErrors); ok {
for _, fieldErr := range validationErr {
var requirement = fieldErr.Tag()
if fieldErr.Param() != "" {
requirement = fieldErr.Tag() + "(" + fieldErr.Param() + ")"
}
allErrors = append(
allErrors,
fmt.Errorf(
"field [%s] requires %s but is %+v",
property,
requirement,
fieldErr.Value(),
),
)
}
}
}
}
if len(allErrors) > 0 {
return &ValidationError{
Message: fmt.Sprintf("Validation failed (%d error(s))", len(allErrors)),
Errors: allErrors,
}
}