validator icon indicating copy to clipboard operation
validator copied to clipboard

Custom rule function `FieldLevel.FieldName()` return empty string on `Validate.ValidateMap()`

Open yz89122 opened this issue 4 years ago • 2 comments

  • [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 "".

yz89122 avatar Jul 28 '21 15:07 yz89122

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.

kokoraka avatar Oct 05 '21 17:10 kokoraka

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,
		}
	}

timofriedlberlin avatar Jan 26 '22 01:01 timofriedlberlin