Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ language: go
go:
- "1.8.x"
- "1.10.x"
- "1.13.x"
- "1.14.x"
19 changes: 0 additions & 19 deletions error.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ package errors

import (
"bytes"
baseErrors "errors"
"fmt"
"reflect"
"runtime"
Expand Down Expand Up @@ -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
Expand Down
26 changes: 26 additions & 0 deletions error_1_13.go
Original file line number Diff line number Diff line change
@@ -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
}
68 changes: 68 additions & 0 deletions error_1_13_test.go
Original file line number Diff line number Diff line change
@@ -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
}
22 changes: 22 additions & 0 deletions error_backward.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// +build !go1.13

package 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,
// or if they both contain the same error inside an errors.Error.
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
}
61 changes: 1 addition & 60 deletions error_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
Expand All @@ -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) {
Expand Down Expand Up @@ -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
}