From f7933685e39a41c3aa6be46b84c9050d91a6198b Mon Sep 17 00:00:00 2001 From: Luiz Ferraz Date: Mon, 24 Jan 2022 18:21:43 -0300 Subject: [PATCH 1/2] Fix match.As to behave the same as errors.As --- match/match.go | 6 +----- match/match_test.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/match/match.go b/match/match.go index eea2f69..72ac7a4 100644 --- a/match/match.go +++ b/match/match.go @@ -74,12 +74,8 @@ func As(target interface{}) ErrorMatcher { panic("errors: *target must be interface or implement error") } - tar := reflect.New(typ).Interface() - return ErrorMatcherFunc(func(err error) bool { - target := tar - - return errors.As(err, &target) + return errors.As(err, target) }) } diff --git a/match/match_test.go b/match/match_test.go index ed6138c..4a0f5bb 100644 --- a/match/match_test.go +++ b/match/match_test.go @@ -2,6 +2,7 @@ package match import ( "errors" + "fmt" "testing" ) @@ -79,6 +80,40 @@ func TestAs(t *testing.T) { } } +type errorData struct { + data string +} + +func (e errorData) Error() string { + return e.data +} + +func TestAs_SetMatchedError(t *testing.T) { + var matchErr errorData + + matcher := As(&matchErr) + + matchingErr := fmt.Errorf("wrapping error: %w", errorData{"target data"}) + + if !matcher.MatchError(matchingErr) { + t.Error("As matcher is not supposed to match an error that cannot be assigned from the error chain") + } + + if matchErr.data != "target data" { + t.Error("As matcher is supposed to set the matched error to it's value in the chain") + } +} + +func TestAs_IncompatibleErrors(t *testing.T) { + var matchErr errorData + + matcher := As(&matchErr) + + if matcher.MatchError(errors.New("error")) { + t.Error("As matcher is not supposed to match an error that cannot be assigned from the error chain") + } +} + func TestAs_Race(t *testing.T) { var matchErr interface { IsError() bool From badf1e15edb050d0a30f72f28f94afea22ddf83d Mon Sep 17 00:00:00 2001 From: Luiz Ferraz Date: Wed, 26 Jan 2022 12:12:04 -0300 Subject: [PATCH 2/2] Replace error wrapping for backward compatibility --- match/match_test.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/match/match_test.go b/match/match_test.go index 4a0f5bb..9eca840 100644 --- a/match/match_test.go +++ b/match/match_test.go @@ -2,7 +2,6 @@ package match import ( "errors" - "fmt" "testing" ) @@ -88,12 +87,20 @@ func (e errorData) Error() string { return e.data } +type wrappingError struct { + error +} + +func (w wrappingError) Unwrap() error { + return w.error +} + func TestAs_SetMatchedError(t *testing.T) { var matchErr errorData matcher := As(&matchErr) - matchingErr := fmt.Errorf("wrapping error: %w", errorData{"target data"}) + matchingErr := wrappingError{error: errorData{"target data"}} if !matcher.MatchError(matchingErr) { t.Error("As matcher is not supposed to match an error that cannot be assigned from the error chain")