mirror of
https://github.com/romdo/go-validate.git
synced 2026-02-18 23:56:41 +00:00
fix(validate): do not panic with field errors on non-struct types
When validating non-struct types, we should not try and convert field values in errors, because there is no struct field to lookup. Hence this fix stops a panic from happening. It is up to the Validate() method itself to provide the correct and final field value when validating non-struct types.
This commit is contained in:
@@ -2,6 +2,7 @@ package validate_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -40,6 +41,29 @@ func (s *validatableStruct) Validate() error {
|
||||
return s.f()
|
||||
}
|
||||
|
||||
type validatableSlice []validatableStruct
|
||||
|
||||
func (s validatableSlice) Validate() error {
|
||||
var errs error
|
||||
|
||||
if len(s) < 1 {
|
||||
errs = validate.AppendError(errs, "must contain at least 1 item")
|
||||
}
|
||||
|
||||
fooVals := map[string]bool{}
|
||||
for i, item := range s {
|
||||
if fooVals[item.Foo] {
|
||||
errs = validate.Append(errs, &validate.Error{
|
||||
Field: fmt.Sprintf("%d.Foo", i),
|
||||
Msg: "is not unique",
|
||||
})
|
||||
}
|
||||
fooVals[item.Foo] = true
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
type nestedStruct struct {
|
||||
OtherField *validatableStruct
|
||||
OtherFieldJSON *validatableStruct `json:"other_field,omitempty"`
|
||||
@@ -122,6 +146,31 @@ func TestValidate(t *testing.T) {
|
||||
&validate.Error{Msg: "must not contain space"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "valid validatable slice type",
|
||||
obj: validatableSlice{
|
||||
{Foo: "Hello"},
|
||||
{Foo: "World"},
|
||||
},
|
||||
wantErrs: []error{},
|
||||
},
|
||||
{
|
||||
name: "invalid validatable slice type",
|
||||
obj: validatableSlice{},
|
||||
wantErrs: []error{
|
||||
&validate.Error{Msg: "must contain at least 1 item"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid validatable slice type with custom field error",
|
||||
obj: validatableSlice{
|
||||
{Foo: "Hello"},
|
||||
{Foo: "Hello"},
|
||||
},
|
||||
wantErrs: []error{
|
||||
&validate.Error{Field: "1.Foo", Msg: "is not unique"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "single Go error",
|
||||
obj: &validatableStruct{f: func() error {
|
||||
|
||||
@@ -83,7 +83,7 @@ func (s *Validator) validate(path []string, data interface{}) error {
|
||||
e := &Error{}
|
||||
if ok := errors.As(err, &e); ok {
|
||||
field := e.Field
|
||||
if field != "" {
|
||||
if field != "" && d.Kind() == reflect.Struct {
|
||||
if sf, ok := d.Type().FieldByName(e.Field); ok {
|
||||
field = s.fieldName(sf)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user