From 31b0a5b4a4c5c635dd19d730e9076826c8138f54 Mon Sep 17 00:00:00 2001 From: tfreville Date: Tue, 2 Jun 2020 08:43:14 +0200 Subject: [PATCH 1/2] (Backward comp): Add build tags to make errors backward compatible --- error.go | 19 ------------- error_1_13.go | 26 ++++++++++++++++++ error_1_13_test.go | 68 ++++++++++++++++++++++++++++++++++++++++++++++ error_backward.go | 22 +++++++++++++++ error_test.go | 61 +---------------------------------------- 5 files changed, 117 insertions(+), 79 deletions(-) create mode 100644 error_1_13.go create mode 100644 error_1_13_test.go create mode 100644 error_backward.go diff --git a/error.go b/error.go index daab7e1..13aa35a 100644 --- a/error.go +++ b/error.go @@ -47,7 +47,6 @@ package errors import ( "bytes" - baseErrors "errors" "fmt" "reflect" "runtime" @@ -140,24 +139,6 @@ func WrapPrefix(e interface{}, prefix string, skip int) *Error { } -// Is detects whether the error is equal to a given error. Errors -// are considered equal by this function if they are matched by errors.Is -// or if their contained errors are matched through errors.Is -func Is(e error, original error) bool { - if baseErrors.Is(e, original) { - return true - } - - if e, ok := e.(*Error); ok { - return Is(e.Err, original) - } - - if original, ok := original.(*Error); ok { - return Is(e, original.Err) - } - - return false -} // Errorf creates a new error with the given message. You can use it // as a drop-in replacement for fmt.Errorf() to provide descriptive diff --git a/error_1_13.go b/error_1_13.go new file mode 100644 index 0000000..a81e24e --- /dev/null +++ b/error_1_13.go @@ -0,0 +1,26 @@ +// +build go1.13 + +package errors + +import ( + baseErrors "errors" +) + +// Is detects whether the error is equal to a given error. Errors +// are considered equal by this function if they are matched by errors.Is +// or if their contained errors are matched through errors.Is +func Is(e error, original error) bool { + if baseErrors.Is(e, original) { + return true + } + + if e, ok := e.(*Error); ok { + return Is(e.Err, original) + } + + if original, ok := original.(*Error); ok { + return Is(e, original.Err) + } + + return false +} diff --git a/error_1_13_test.go b/error_1_13_test.go new file mode 100644 index 0000000..92d3326 --- /dev/null +++ b/error_1_13_test.go @@ -0,0 +1,68 @@ +// +build go1.13 + +package errors + +import ( + "io" + "testing" +) + +// This test should work only for go 1.13 and latter +func TestIs113(t *testing.T) { + custErr := errorWithCustomIs{ + Key: "TestForFun", + Err: io.EOF, + } + + shouldMatch := errorWithCustomIs{ + Key: "TestForFun", + } + + shouldNotMatch := errorWithCustomIs{Key: "notOk"} + + if !Is(custErr, shouldMatch) { + t.Errorf("custErr is not a TestForFun customError") + } + + if Is(custErr, shouldNotMatch) { + t.Errorf("custErr is a notOk customError") + } + + if !Is(custErr, New(shouldMatch)) { + t.Errorf("custErr is not a New(TestForFun customError)") + } + + if Is(custErr, New(shouldNotMatch)) { + t.Errorf("custErr is a New(notOk customError)") + } + + if !Is(New(custErr), shouldMatch) { + t.Errorf("New(custErr) is not a TestForFun customError") + } + + if Is(New(custErr), shouldNotMatch) { + t.Errorf("New(custErr) is a notOk customError") + } + + if !Is(New(custErr), New(shouldMatch)) { + t.Errorf("New(custErr) is not a New(TestForFun customError)") + } + + if Is(New(custErr), New(shouldNotMatch)) { + t.Errorf("New(custErr) is a New(notOk customError)") + } +} + +type errorWithCustomIs struct { + Key string + Err error +} + +func (ewci errorWithCustomIs) Error() string { + return "["+ewci.Key+"]: " + ewci.Err.Error() +} + +func (ewci errorWithCustomIs) Is(target error) bool { + matched, ok := target.(errorWithCustomIs) + return ok && matched.Key == ewci.Key +} \ No newline at end of file diff --git a/error_backward.go b/error_backward.go new file mode 100644 index 0000000..de0164b --- /dev/null +++ b/error_backward.go @@ -0,0 +1,22 @@ +// +build !go1.13 + +package errors + +// Is detects whether the error is equal to a given error. Errors // Is detects whether the error is equal to a given error. Errors +// are considered equal by this function if they are the same object, // are considered equal by this function if they are matched by errors.Is +// or if they both contain the same error inside an errors.Error. // or if their contained errors are matched through errors.Is +func Is(e error, original error) bool { + if e == original { + return true + } + + if e, ok := e.(*Error); ok { + return Is(e.Err, original) + } + + if original, ok := original.(*Error); ok { + return Is(e, original.Err) + } + + return false +} \ No newline at end of file diff --git a/error_test.go b/error_test.go index 76f2f2e..d7b11f9 100644 --- a/error_test.go +++ b/error_test.go @@ -107,8 +107,8 @@ func TestNew(t *testing.T) { } } +// This test should work for any go version func TestIs(t *testing.T) { - if Is(nil, io.EOF) { t.Errorf("nil is an error") } @@ -128,51 +128,6 @@ func TestIs(t *testing.T) { if Is(io.EOF, fmt.Errorf("io.EOF")) { t.Errorf("io.EOF is fmt.Errorf") } - - custErr := errorWithCustomIs{ - Key: "TestForFun", - Err: io.EOF, - } - - shouldMatch := errorWithCustomIs{ - Key: "TestForFun", - } - - shouldNotMatch := errorWithCustomIs{Key: "notOk"} - - if !Is(custErr, shouldMatch) { - t.Errorf("custErr is not a TestForFun customError") - } - - if Is(custErr, shouldNotMatch) { - t.Errorf("custErr is a notOk customError") - } - - if !Is(custErr, New(shouldMatch)) { - t.Errorf("custErr is not a New(TestForFun customError)") - } - - if Is(custErr, New(shouldNotMatch)) { - t.Errorf("custErr is a New(notOk customError)") - } - - if !Is(New(custErr), shouldMatch) { - t.Errorf("New(custErr) is not a TestForFun customError") - } - - if Is(New(custErr), shouldNotMatch) { - t.Errorf("New(custErr) is a notOk customError") - } - - if !Is(New(custErr), New(shouldMatch)) { - t.Errorf("New(custErr) is not a New(TestForFun customError)") - } - - if Is(New(custErr), New(shouldNotMatch)) { - t.Errorf("New(custErr) is a New(notOk customError)") - } - - } func TestWrapError(t *testing.T) { @@ -361,17 +316,3 @@ func callersToFrames(callers []uintptr) []runtime.Frame { } } } - -type errorWithCustomIs struct { - Key string - Err error -} - -func (ewci errorWithCustomIs) Error() string { - return "["+ewci.Key+"]: " + ewci.Err.Error() -} - -func (ewci errorWithCustomIs) Is(target error) bool { - matched, ok := target.(errorWithCustomIs) - return ok && matched.Key == ewci.Key -} \ No newline at end of file From 7da7452d47d2761a99ad3f9c420d00d943565661 Mon Sep 17 00:00:00 2001 From: tfreville Date: Tue, 2 Jun 2020 08:53:34 +0200 Subject: [PATCH 2/2] Add go 1.13,1.14 to travis --- .travis.yml | 2 ++ error_backward.go | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9d00fdd..fddfc4e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,3 +3,5 @@ language: go go: - "1.8.x" - "1.10.x" + - "1.13.x" + - "1.14.x" diff --git a/error_backward.go b/error_backward.go index de0164b..d7e09a8 100644 --- a/error_backward.go +++ b/error_backward.go @@ -2,9 +2,9 @@ package errors -// Is detects whether the error is equal to a given error. Errors // Is detects whether the error is equal to a given error. Errors -// are considered equal by this function if they are the same object, // are considered equal by this function if they are matched by errors.Is -// or if they both contain the same error inside an errors.Error. // or if their contained errors are matched through errors.Is +// Is detects whether the error is equal to a given error. Errors +// are considered equal by this function if they are the same object, +// or if they both contain the same error inside an errors.Error. func Is(e error, original error) bool { if e == original { return true