Repository: gin-gonic/gin
Pull request #2526 (2020-10-09 17:12:28)

implement ".Unwrap() error" on Error type (#2525)
Implement `.Unwrap() error` method on type `Error`, to be compatible with stdlib `errors.Is()` and `erors.As()` functions.

codecov[bot]: # [Codecov](https://codecov.io/gh/gin-gonic/gin/pull/2526?src=pr&el=h1) Report
> Merging [#2526](https://codecov.io/gh/gin-gonic/gin/pull/2526?src=pr&el=desc) into [master](https://codecov.io/gh/gin-gonic/gin/commit/540b1eff7069128df5d95e09968569f2266d9a6a?el=desc) will **decrease** coverage by `0.01%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/gin-gonic/gin/pull/2526/graphs/tree.svg?width=650&height=150&src=pr&token=Qpqxhwery8)](https://codecov.io/gh/gin-gonic/gin/pull/2526?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #2526      +/-   ##
==========================================
- Coverage   98.45%   98.44%   -0.02%     
==========================================
  Files          41       40       -1     
  Lines        1948     1931      -17     
==========================================
- Hits         1918     1901      -17     
  Misses         17       17              
  Partials       13       13              
```


| [Impacted Files](https://codecov.io/gh/gin-gonic/gin/pull/2526?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [errors.go](https://codecov.io/gh/gin-gonic/gin/pull/2526/diff?src=pr&el=tree#diff-ZXJyb3JzLmdv) | `100.00% <100.00%> (ø)` | |
| [binding/binding\_nomsgpack.go](https://codecov.io/gh/gin-gonic/gin/pull/2526/diff?src=pr&el=tree#diff-YmluZGluZy9iaW5kaW5nX25vbXNncGFjay5nbw==) | | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/gin-gonic/gin/pull/2526?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/gin-gonic/gin/pull/2526?src=pr&el=footer). Last update [540b1ef...8a570b9](https://codecov.io/gh/gin-gonic/gin/pull/2526?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/errors.go b/errors.go
index 9a31799..0f276c1 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 {


Test patch:
diff --git a/errors_1.13_test.go b/errors_1.13_test.go
new file mode 100644
index 0000000..a8f9a94
--- /dev/null
+++ b/errors_1.13_test.go
@@ -0,0 +1,33 @@
+// +build go1.13
+
+package gin
+
+import (
+	"errors"
+	"fmt"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+type TestErr string
+
+func (e TestErr) Error() string { return string(e) }
+
+// TestErrorUnwrap tests the behavior of gin.Error with "errors.Is()" and "errors.As()".
+// "errors.Is()" and "errors.As()" have been added to the standard library in go 1.13,
+// hence the "// +build go1.13" directive at the beginning of this file.
+func TestErrorUnwrap(t *testing.T) {
+	innerErr := TestErr("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 TestErr
+	assert.True(t, errors.As(err, &testErr))
+}