From aedb258110b12d9ea267db988fe46b6a7a987a96 Mon Sep 17 00:00:00 2001 From: Max Chechel Date: Fri, 31 Aug 2018 11:24:08 +0300 Subject: [PATCH 1/3] Don't wrap error from custom validator to unknown_field --- errlist/errlist.go | 30 ++++++++++++++++++------------ errlist/errlist_test.go | 2 +- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/errlist/errlist.go b/errlist/errlist.go index 08f541f..ab32cd5 100644 --- a/errlist/errlist.go +++ b/errlist/errlist.go @@ -6,7 +6,7 @@ import ( "github.com/pkg/errors" ) -type List []Field +type List []error // Error implements `error` interface func (e List) Error() string { @@ -31,7 +31,8 @@ func (e *List) Add(err error) *List { list, ok := err.(List) if !ok { - return e.AddField(UnknownField, err) + *e = append(*e, err) + return e } for _, fe := range list { *e = append(*e, fe) @@ -48,10 +49,14 @@ func (e *List) AddField(field string, err error) *List { return e } - switch errTyped := err.(type) { + switch v := err.(type) { case List: - for _, childErr := range errTyped { - *e = append(*e, Field{Field: field + "." + childErr.Field, Err: childErr.Err}) + for _, err := range v { + if fieldErr, ok := err.(Field); ok { + *e = append(*e, Field{Field: field + "." + fieldErr.Field, Err: fieldErr.Err}) + } else { + *e = append(*e, err) + } } case error: *e = append(*e, Field{Field: field, Err: err}) @@ -60,13 +65,14 @@ func (e *List) AddField(field string, err error) *List { return e } -func (e List) HasErrors() bool { - return len(e) > 0 -} - func (e List) ErrorOrNil() error { - if e.HasErrors() { - return e + if len(e) == 0 { + return nil } - return nil + + if len(e) == 1 { + return e[0] + } + + return e } diff --git a/errlist/errlist_test.go b/errlist/errlist_test.go index 0bca2ca..674b3e7 100644 --- a/errlist/errlist_test.go +++ b/errlist/errlist_test.go @@ -50,7 +50,7 @@ func Test_List_Add(t *testing.T) { errs1.AddField("1", errors.New("a")) errs1.Add(errors.New("b")) - assert.Equal(t, `[1: a, unknown: b]`, errs1.Error()) + assert.Equal(t, `[1: a, b]`, errs1.Error()) }) t.Run("many errors", func(t *testing.T) { From 81730f5aa5893837b87da3d364425bb12b0413c2 Mon Sep 17 00:00:00 2001 From: Max Chechel Date: Fri, 31 Aug 2018 12:18:53 +0300 Subject: [PATCH 2/3] master fixed tests --- errlist/errlist.go | 4 +++- examples/aliases/entities_test.go | 6 +++--- examples/complicated/entities_test.go | 18 +++++++++--------- examples/overriding/ex1_full_test.go | 2 +- examples/overriding/ex2_by_method_test.go | 8 ++++---- examples/overriding/ex3_by_func_test.go | 10 +++++----- .../overriding/ex4_by_method_and_func_test.go | 8 ++++---- examples/overriding/ex5_additional_test.go | 14 +++++++------- examples/simple/entities_test.go | 16 ++++++++-------- 9 files changed, 44 insertions(+), 42 deletions(-) diff --git a/errlist/errlist.go b/errlist/errlist.go index ab32cd5..f31ef5a 100644 --- a/errlist/errlist.go +++ b/errlist/errlist.go @@ -58,7 +58,9 @@ func (e *List) AddField(field string, err error) *List { *e = append(*e, err) } } - case error: + case Field: + *e = append(*e, errors.Errorf("%s.%v", field, v.Error())) + default: *e = append(*e, Field{Field: field, Err: err}) } diff --git a/examples/aliases/entities_test.go b/examples/aliases/entities_test.go index fadc7ee..f369f17 100644 --- a/examples/aliases/entities_test.go +++ b/examples/aliases/entities_test.go @@ -64,7 +64,7 @@ func Test_User_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[SomePointer: shorter than 20 chars]`, err.Error()) + assert.Equal(t, `SomePointer: shorter than 20 chars`, err.Error()) }) t.Run("non_empty_string: using func validator", func(t *testing.T) { @@ -73,7 +73,7 @@ func Test_User_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[NonEmptyString: string is empty]`, err.Error()) + assert.Equal(t, `NonEmptyString: string is empty`, err.Error()) }) t.Run("SomePointerNullable: valid", func(*testing.T) { @@ -92,7 +92,7 @@ func Test_User_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[SomePointerNullable: shorter than 3 chars]`, err.Error()) + assert.Equal(t, `SomePointerNullable: shorter than 3 chars`, err.Error()) }) }) } diff --git a/examples/complicated/entities_test.go b/examples/complicated/entities_test.go index a1da708..ac04551 100644 --- a/examples/complicated/entities_test.go +++ b/examples/complicated/entities_test.go @@ -70,7 +70,7 @@ func Test_Request1_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[Name: shorter than 3 chars]`, err.Error()) + assert.Equal(t, `Name: shorter than 3 chars`, err.Error()) }) t.Run("last_name: too short", func(t *testing.T) { @@ -80,7 +80,7 @@ func Test_Request1_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[LastName: shorter than 1 chars]`, err.Error()) + assert.Equal(t, `LastName: shorter than 1 chars`, err.Error()) }) t.Run("last_name: empty", func(t *testing.T) { @@ -97,7 +97,7 @@ func Test_Request1_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[Age: less than 18]`, err.Error()) + assert.Equal(t, `Age: less than 18`, err.Error()) }) t.Run("children_count: not_null rule", func(t *testing.T) { @@ -106,7 +106,7 @@ func Test_Request1_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[ChildrenCount: cannot be nil]`, err.Error()) + assert.Equal(t, `ChildrenCount: cannot be nil`, err.Error()) }) t.Run("children_count: too much", func(t *testing.T) { @@ -116,7 +116,7 @@ func Test_Request1_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[ChildrenCount: more than 15]`, err.Error()) + assert.Equal(t, `ChildrenCount: more than 15`, err.Error()) }) t.Run("dog_pointer: nil is ok", func(t *testing.T) { @@ -133,7 +133,7 @@ func Test_Request1_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[DogPointer.Name: shorter than 1 chars]`, err.Error()) + assert.Equal(t, `DogPointer.Name: shorter than 1 chars`, err.Error()) }) t.Run("alias: alias type validator", func(t *testing.T) { @@ -162,7 +162,7 @@ func Test_Request1_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[MapOfMap.key.1: shorter than 3 chars]`, err.Error()) + assert.Equal(t, `MapOfMap.key.1: shorter than 3 chars`, err.Error()) }) t.Run("SliceOfMap: invalid key", func(t *testing.T) { @@ -175,7 +175,7 @@ func Test_Request1_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[SliceOfMap.0.key[k]: shorter than 3 chars]`, err.Error()) + assert.Equal(t, `SliceOfMap.0.key[k]: shorter than 3 chars`, err.Error()) }) t.Run("SliceOfSliceOfSlice: invalid length", func(t *testing.T) { @@ -193,7 +193,7 @@ func Test_Request1_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[SliceOfSliceOfSlice.1.0: less items than 1]`, err.Error()) + assert.Equal(t, `SliceOfSliceOfSlice.1.0: less items than 1`, err.Error()) }) }) } diff --git a/examples/overriding/ex1_full_test.go b/examples/overriding/ex1_full_test.go index 0745d4d..d9c4507 100644 --- a/examples/overriding/ex1_full_test.go +++ b/examples/overriding/ex1_full_test.go @@ -44,7 +44,7 @@ func Test_Request1_Validate(t *testing.T) { err := r.Age.Validate() require.NotNil(t, err) - assert.Equal(t, `[Value: more than 64]`, err.Error()) + assert.Equal(t, `Value: more than 64`, err.Error()) }) t.Run("check min.", func(t *testing.T) { diff --git a/examples/overriding/ex2_by_method_test.go b/examples/overriding/ex2_by_method_test.go index 9634287..bdebb50 100644 --- a/examples/overriding/ex2_by_method_test.go +++ b/examples/overriding/ex2_by_method_test.go @@ -26,7 +26,7 @@ func Test_Request2_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[Age: field Age is less than 10]`, err.Error()) + assert.Equal(t, `Age: field Age is less than 10`, err.Error()) }) t.Run("too young, using generated type validator", func(t *testing.T) { @@ -61,7 +61,7 @@ func Test_Request2_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[Age: field Age is more than 64]`, err.Error()) + assert.Equal(t, `Age: field Age is more than 64`, err.Error()) }) t.Run("check min.", func(t *testing.T) { @@ -70,7 +70,7 @@ func Test_Request2_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[Some: less than 3]`, err.Error()) + assert.Equal(t, `Some: less than 3`, err.Error()) }) t.Run("check max.", func(t *testing.T) { @@ -79,7 +79,7 @@ func Test_Request2_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[Some: more than 64]`, err.Error()) + assert.Equal(t, `Some: more than 64`, err.Error()) }) }) diff --git a/examples/overriding/ex3_by_func_test.go b/examples/overriding/ex3_by_func_test.go index 2daeb55..6d38718 100644 --- a/examples/overriding/ex3_by_func_test.go +++ b/examples/overriding/ex3_by_func_test.go @@ -26,7 +26,7 @@ func Test_Request3_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[Age: field Age is less than 10]`, err.Error()) + assert.Equal(t, `Age: field Age is less than 10`, err.Error()) }) t.Run("too old, using overridden rule", func(t *testing.T) { @@ -35,7 +35,7 @@ func Test_Request3_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[Age: field Age is more than 64]`, err.Error()) + assert.Equal(t, `Age: field Age is more than 64`, err.Error()) }) t.Run("too young, using generated type validator", func(t *testing.T) { @@ -52,7 +52,7 @@ func Test_Request3_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[Age: field Age is more than 64]`, err.Error()) + assert.Equal(t, `Age: field Age is more than 64`, err.Error()) }) t.Run("check min.", func(t *testing.T) { @@ -61,7 +61,7 @@ func Test_Request3_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[Some: less than 3]`, err.Error()) + assert.Equal(t, `Some: less than 3`, err.Error()) }) t.Run("check max.", func(t *testing.T) { @@ -70,7 +70,7 @@ func Test_Request3_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[Some: more than 64]`, err.Error()) + assert.Equal(t, `Some: more than 64`, err.Error()) }) }) diff --git a/examples/overriding/ex4_by_method_and_func_test.go b/examples/overriding/ex4_by_method_and_func_test.go index e0a6483..863378b 100644 --- a/examples/overriding/ex4_by_method_and_func_test.go +++ b/examples/overriding/ex4_by_method_and_func_test.go @@ -26,7 +26,7 @@ func Test_Request4_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[Age: field Age is less than 10]`, err.Error()) + assert.Equal(t, `Age: field Age is less than 10`, err.Error()) }) t.Run("too young, using func validator", func(t *testing.T) { @@ -68,7 +68,7 @@ func Test_Request4_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[Age: field Age is more than 128]`, err.Error()) + assert.Equal(t, `Age: field Age is more than 128`, err.Error()) }) t.Run("check min.", func(t *testing.T) { @@ -77,7 +77,7 @@ func Test_Request4_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[Some: less than 3]`, err.Error()) + assert.Equal(t, `Some: less than 3`, err.Error()) }) t.Run("check max.", func(t *testing.T) { @@ -86,7 +86,7 @@ func Test_Request4_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[Some: more than 64]`, err.Error()) + assert.Equal(t, `Some: more than 64`, err.Error()) }) }) diff --git a/examples/overriding/ex5_additional_test.go b/examples/overriding/ex5_additional_test.go index 9dd1224..61b0b4c 100644 --- a/examples/overriding/ex5_additional_test.go +++ b/examples/overriding/ex5_additional_test.go @@ -27,7 +27,7 @@ func Test_Request5_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[unknown: fields Age and Some can't be 10 at the same time]`, err.Error()) + assert.Equal(t, `fields Age and Some can't be 10 at the same time`, err.Error()) }) t.Run("too young, using generated type validator", func(t *testing.T) { @@ -36,7 +36,7 @@ func Test_Request5_Validate(t *testing.T) { err := r.Age.Validate() require.NotNil(t, err) - assert.Equal(t, `[Value: less than 3]`, err.Error()) + assert.Equal(t, `Value: less than 3`, err.Error()) }) t.Run("too old, using generated type validator", func(t *testing.T) { @@ -45,7 +45,7 @@ func Test_Request5_Validate(t *testing.T) { err := r.Age.Validate() require.NotNil(t, err) - assert.Equal(t, `[Value: more than 64]`, err.Error()) + assert.Equal(t, `Value: more than 64`, err.Error()) }) t.Run("too young, using generated validator", func(t *testing.T) { @@ -54,7 +54,7 @@ func Test_Request5_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[Age.Value: less than 3]`, err.Error()) + assert.Equal(t, `Age.Value: less than 3`, err.Error()) }) t.Run("too old, using generated validator", func(t *testing.T) { @@ -63,7 +63,7 @@ func Test_Request5_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[Age.Value: more than 64]`, err.Error()) + assert.Equal(t, `Age.Value: more than 64`, err.Error()) }) t.Run("check min.", func(t *testing.T) { @@ -72,7 +72,7 @@ func Test_Request5_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[Some: less than 3]`, err.Error()) + assert.Equal(t, `Some: less than 3`, err.Error()) }) t.Run("check max.", func(t *testing.T) { @@ -81,7 +81,7 @@ func Test_Request5_Validate(t *testing.T) { err := r.Validate() require.NotNil(t, err) - assert.Equal(t, `[Some: more than 64]`, err.Error()) + assert.Equal(t, `Some: more than 64`, err.Error()) }) }) diff --git a/examples/simple/entities_test.go b/examples/simple/entities_test.go index 8528117..d0e4e52 100644 --- a/examples/simple/entities_test.go +++ b/examples/simple/entities_test.go @@ -31,7 +31,7 @@ func Test_User_Validate(t *testing.T) { err := user.Validate() require.NotNil(t, err) - assert.Equal(t, `[Name: shorter than 3 chars]`, err.Error()) + assert.Equal(t, `Name: shorter than 3 chars`, err.Error()) }) t.Run("too long name", func(t *testing.T) { @@ -40,7 +40,7 @@ func Test_User_Validate(t *testing.T) { err := user.Validate() require.NotNil(t, err) - assert.Equal(t, `[Name: longer than 64 chars]`, err.Error()) + assert.Equal(t, `Name: longer than 64 chars`, err.Error()) }) t.Run("nil title", func(t *testing.T) { @@ -49,7 +49,7 @@ func Test_User_Validate(t *testing.T) { err := user.Validate() require.NotNil(t, err) - assert.Equal(t, "[Title: cannot be nil]", err.Error()) + assert.Equal(t, "Title: cannot be nil", err.Error()) }) t.Run("bad title", func(t *testing.T) { @@ -59,7 +59,7 @@ func Test_User_Validate(t *testing.T) { err := user.Validate() require.NotNil(t, err) - assert.Equal(t, "[Title: invalid value for enum Title: Jedi]", err.Error()) + assert.Equal(t, "Title: invalid value for enum Title: Jedi", err.Error()) }) t.Run("no email", func(t *testing.T) { @@ -68,7 +68,7 @@ func Test_User_Validate(t *testing.T) { err := user.Validate() require.NotNil(t, err) - assert.Equal(t, "[Emails: less items than 1]", err.Error()) + assert.Equal(t, "Emails: less items than 1", err.Error()) }) t.Run("bad email key and value", func(t *testing.T) { @@ -86,7 +86,7 @@ func Test_User_Validate(t *testing.T) { err := user.Validate() require.NotNil(t, err) - assert.Equal(t, `[Age: less than 18]`, err.Error()) + assert.Equal(t, `Age: less than 18`, err.Error()) }) t.Run("too old", func(t *testing.T) { @@ -95,7 +95,7 @@ func Test_User_Validate(t *testing.T) { err := user.Validate() require.NotNil(t, err) - assert.Equal(t, `[Age: more than 95]`, err.Error()) + assert.Equal(t, `Age: more than 95`, err.Error()) }) t.Run("bad dog", func(t *testing.T) { @@ -104,7 +104,7 @@ func Test_User_Validate(t *testing.T) { err := user.Validate() require.NotNil(t, err) - assert.Equal(t, `[Dog.Name: shorter than 1 chars]`, err.Error()) + assert.Equal(t, `Dog.Name: shorter than 1 chars`, err.Error()) }) }) } From 0dd8f11c168c55287dcaccf0289b9871087f8afb Mon Sep 17 00:00:00 2001 From: Max Chechel Date: Fri, 31 Aug 2018 12:28:22 +0300 Subject: [PATCH 3/3] updated .travis.yml and removed UnknownField constant --- .travis.yml | 4 ++-- errlist/fielderr.go | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 141f477..301d0b1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,10 @@ language: go go: - - 1.7 + - 1.X - tip install: - go get github.com/pkg/errors - go get github.com/stretchr/testify/assert - - go get github.com/stretchr/testify/require \ No newline at end of file + - go get github.com/stretchr/testify/require diff --git a/errlist/fielderr.go b/errlist/fielderr.go index e189e2a..1db5d55 100644 --- a/errlist/fielderr.go +++ b/errlist/fielderr.go @@ -6,8 +6,6 @@ import ( "github.com/pkg/errors" ) -const UnknownField = "unknown" - type Field struct { Field string `json:"field"` Err error `json:"err"`