From 8a570b9837a8d704f422785becbaeb659d338dfc Mon Sep 17 00:00:00 2001 From: Georges Varouchas Date: Fri, 9 Oct 2020 19:02:59 +0200 Subject: [PATCH] implement ".Unwrap() error" on Error type (#2525) --- errors.go | 5 +++++ errors_test.go | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/errors.go b/errors.go index 9a31799273..0f276c13d4 100644 --- a/errors.go +++ b/errors.go @@ -90,6 +90,11 @@ func (msg *Error) IsType(flags ErrorType) bool { return (msg.Type & flags) > 0 } +// Unwrap returns the wrapped error, to allow interoperability with errors.Is(), errors.As() and errors.Unwrap() +func (msg *Error) Unwrap() error { + return msg.Err +} + // ByType returns a readonly copy filtered the byte. // ie ByType(gin.ErrorTypePublic) returns a slice of errors with type=ErrorTypePublic. func (a errorMsgs) ByType(typ ErrorType) errorMsgs { diff --git a/errors_test.go b/errors_test.go index 6aae1c10b3..fb4fecb8cc 100644 --- a/errors_test.go +++ b/errors_test.go @@ -6,6 +6,7 @@ package gin import ( "errors" + "fmt" "testing" "github.com/gin-gonic/gin/internal/json" @@ -104,3 +105,22 @@ Error #03: third assert.Nil(t, errs.JSON()) assert.Empty(t, errs.String()) } + +type TestStrErr string + +func (e TestStrErr) Error() string { return string(e) } + +func TestErrorUnwrap(t *testing.T) { + innerErr := TestStrErr("somme error") + + // 2 layers of wrapping : use 'fmt.Errorf("%w")' to wrap a gin.Error{}, which itself wraps innerErr + err := fmt.Errorf("wrapped: %w", &Error{ + Err: innerErr, + Type: ErrorTypeAny, + }) + + // check that 'errors.Is()' and 'errors.As()' behave as expected : + assert.True(t, errors.Is(err, innerErr)) + var testErr TestStrErr + assert.True(t, errors.As(err, &testErr)) +}