feat: introduce binding.FieldError type to tell the erroneous field

Signed-off-by: Maxime Soulé <btik-git@scoubidou.com>
This commit is contained in:
Maxime Soulé 2022-01-13 23:40:38 +01:00
parent c4580944ae
commit ee1273206c
2 changed files with 47 additions and 2 deletions

View File

@ -26,6 +26,29 @@ var (
ErrConvertToMapString = errors.New("can not convert to map of strings") ErrConvertToMapString = errors.New("can not convert to map of strings")
) )
type FieldError struct {
Field string
Err error
}
func NewFieldError(field string, err error) error {
if err == nil {
return nil
}
return &FieldError{
Field: field,
Err: err,
}
}
func (e *FieldError) Error() string {
return fmt.Sprintf("field %q error: %s", e.Field, e.Err)
}
func (e *FieldError) Unwrap() error {
return e.Err
}
func mapURI(ptr any, m map[string][]string) error { func mapURI(ptr any, m map[string][]string) error {
return mapFormByTag(ptr, m, "uri") return mapFormByTag(ptr, m, "uri")
} }
@ -161,7 +184,11 @@ func tryToSetValue(value reflect.Value, field reflect.StructField, setter setter
} }
} }
return setter.TrySet(value, field, tagValue, setOpt) ok, err := setter.TrySet(value, field, tagValue, setOpt)
if err != nil {
return ok, NewFieldError(tagValue, err)
}
return ok, nil
} }
func setByForm(value reflect.Value, field reflect.StructField, form map[string][]string, tagValue string, opt setOptions) (isSet bool, err error) { func setByForm(value reflect.Value, field reflect.StructField, form map[string][]string, tagValue string, opt setOptions) (isSet bool, err error) {

View File

@ -5,6 +5,7 @@
package binding package binding
import ( import (
"errors"
"reflect" "reflect"
"testing" "testing"
"time" "time"
@ -124,7 +125,7 @@ func TestMappingUnknownFieldType(t *testing.T) {
err := mappingByPtr(&s, formSource{"U": {"unknown"}}, "form") err := mappingByPtr(&s, formSource{"U": {"unknown"}}, "form")
assert.Error(t, err) assert.Error(t, err)
assert.Equal(t, errUnknownType, err) assert.Equal(t, &FieldError{"U", errUnknownType}, err)
} }
func TestMappingURI(t *testing.T) { func TestMappingURI(t *testing.T) {
@ -288,3 +289,20 @@ func TestMappingIgnoredCircularRef(t *testing.T) {
err := mappingByPtr(&s, formSource{}, "form") err := mappingByPtr(&s, formSource{}, "form")
assert.NoError(t, err) assert.NoError(t, err)
} }
func TestNewField(t *testing.T) {
assert.NoError(t, NewFieldError("foo", nil))
orig := errors.New("bad value")
err := NewFieldError("foo", orig)
if assert.Error(t, err) {
assert.Equal(t, `field "foo" error: bad value`, err.Error())
if fieldErr, ok := err.(*FieldError); assert.True(t, ok) { //nolint: errorlint
assert.Equal(t, fieldErr.Field, "foo")
assert.Equal(t, fieldErr.Err, orig)
}
assert.Equal(t, orig, errors.Unwrap(err))
}
}