From b3b5be818021f953daaded46ca2b35b9373697de Mon Sep 17 00:00:00 2001 From: Dan Jones Date: Tue, 30 Sep 2025 13:51:45 -0500 Subject: [PATCH 1/2] Add Errors.Unwrap method This allows us to use errors.Is with errors returned from a failed validation. --- error.go | 11 +++++++++++ error_test.go | 16 ++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/error.go b/error.go index e75b1de..fa0e2e2 100644 --- a/error.go +++ b/error.go @@ -141,6 +141,17 @@ func (es Errors) Error() string { return s.String() } +// Unwrap returns a slice of the non-nil errors in the Errors. +func (es Errors) Unwrap() []error { + errs := make([]error, 0, len(es)) + for _, err := range es { + if err != nil { + errs = append(errs, err) + } + } + return errs +} + // MarshalJSON converts the Errors into a valid JSON. func (es Errors) MarshalJSON() ([]byte, error) { errs := map[string]interface{}{} diff --git a/error_test.go b/error_test.go index e0985c5..25b3f6c 100644 --- a/error_test.go +++ b/error_test.go @@ -70,6 +70,22 @@ func TestErrors_Filter(t *testing.T) { assert.Nil(t, errs.Filter()) } +func TestErrors_Unwrap(t *testing.T) { + errs := Errors{ + "B": errors.New("B1"), + "C": nil, + "A": errors.New("A1"), + } + + unwrapped := errs.Unwrap() + assert.Contains(t, unwrapped, errs["B"]) + assert.Contains(t, unwrapped, errs["A"]) + assert.Len(t, unwrapped, 2) + + assert.True(t, errors.Is(errs, errs["B"])) + assert.True(t, errors.Is(errs, errs["A"])) +} + func TestErrorObject_SetCode(t *testing.T) { err := NewError("A", "msg").(ErrorObject) From 4f57da59cfeff914c8612d832d369153acdb1ea0 Mon Sep 17 00:00:00 2001 From: Dan Jones Date: Tue, 30 Sep 2025 15:44:06 -0500 Subject: [PATCH 2/2] Remove errors.Is test This only works from go1.20 onwards. And this project targets 1.13 --- error_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/error_test.go b/error_test.go index 25b3f6c..91eb5d5 100644 --- a/error_test.go +++ b/error_test.go @@ -81,9 +81,6 @@ func TestErrors_Unwrap(t *testing.T) { assert.Contains(t, unwrapped, errs["B"]) assert.Contains(t, unwrapped, errs["A"]) assert.Len(t, unwrapped, 2) - - assert.True(t, errors.Is(errs, errs["B"])) - assert.True(t, errors.Is(errs, errs["A"])) } func TestErrorObject_SetCode(t *testing.T) {