Skip to content

Commit 35dc722

Browse files
committed
unwrap errors ahen checking for errorx type
1 parent c749e95 commit 35dc722

5 files changed

Lines changed: 90 additions & 24 deletions

File tree

error.go

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -103,22 +103,6 @@ func (e *Error) HasTrait(key Trait) bool {
103103
return false
104104
}
105105

106-
// IsOfType is a proper type check for an errorx-based errors.
107-
// It takes the transparency and error types hierarchy into account,
108-
// so that type check against any supertype of the original cause passes.
109-
func (e *Error) IsOfType(t *Type) bool {
110-
cause := e
111-
for cause != nil {
112-
if !cause.transparent {
113-
return cause.errorType.IsOfType(t)
114-
}
115-
116-
cause = Cast(cause.Cause())
117-
}
118-
119-
return false
120-
}
121-
122106
// Type returns the exact type of this error.
123107
// With transparent wrapping, such as in Decorate(), returns the type of the original cause.
124108
// The result is always not nil, even if the resulting type is impossible to successfully type check against.

error_112.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// +build !go1.13
2+
3+
package errorx
4+
5+
// IsOfType is a type check for errors.
6+
// Returns true either if both are of exactly the same type, or if the same is true for one of current type's ancestors.
7+
// For an error that does not have an errorx type, returns false.
8+
func IsOfType(err error, t *Type) bool {
9+
e := Cast(err)
10+
return e != nil && e.IsOfType(t)
11+
}
12+
13+
// IsOfType is a proper type check for an errorx-based errors.
14+
// It takes the transparency and error types hierarchy into account,
15+
// so that type check against any supertype of the original cause passes.
16+
func (e *Error) IsOfType(t *Type) bool {
17+
cause := e
18+
for cause != nil {
19+
if !cause.transparent {
20+
return cause.errorType.IsOfType(t)
21+
}
22+
23+
cause = Cast(cause.Cause())
24+
}
25+
26+
return false
27+
}
28+
29+

error_113.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// +build go1.13
2+
3+
package errorx
4+
5+
import "errors"
6+
7+
// IsOfType is a type check for errors.
8+
// Returns true either if both are of exactly the same type, or if the same is true for one of current type's ancestors.
9+
// For an error that does not have an errorx type, returns false.
10+
func IsOfType(err error, t *Type) bool {
11+
e := burrowForTyped(err)
12+
return e != nil && e.IsOfType(t)
13+
}
14+
15+
16+
// IsOfType is a proper type check for an errorx-based errors.
17+
// It takes the transparency and error types hierarchy into account,
18+
// so that type check against any supertype of the original cause passes.
19+
func (e *Error) IsOfType(t *Type) bool {
20+
cause := e
21+
for cause != nil {
22+
if !cause.transparent {
23+
return cause.errorType.IsOfType(t)
24+
}
25+
26+
cause = burrowForTyped(cause.Cause())
27+
}
28+
29+
return false
30+
}
31+
32+
func burrowForTyped(err error) *Error {
33+
raw := err
34+
for raw != nil {
35+
typed := Cast(raw)
36+
if typed != nil {
37+
return typed
38+
}
39+
40+
raw = errors.Unwrap(raw)
41+
}
42+
43+
return nil
44+
}
45+
46+

error_113_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package errorx
44

55
import (
66
"errors"
7+
"fmt"
78
"io"
89
"testing"
910

@@ -103,3 +104,17 @@ func TestErrorIs(t *testing.T) {
103104
require.True(t, errors.Is(err, io.EOF))
104105
})
105106
}
107+
108+
func TestErrorsAndErrorx(t *testing.T) {
109+
t.Run("DecoratedForeign", func(t *testing.T) {
110+
err := fmt.Errorf("error test: %w", testType.NewWithNoMessage())
111+
require.True(t, errors.Is(err, testType.NewWithNoMessage()))
112+
require.True(t, IsOfType(err, testType))
113+
})
114+
115+
t.Run("LayeredDecorate", func(t *testing.T) {
116+
err := Decorate(fmt.Errorf("error test: %w", testType.NewWithNoMessage()), "test")
117+
require.True(t, errors.Is(err, testType.NewWithNoMessage()))
118+
require.True(t, IsOfType(err, testType))
119+
})
120+
}

type.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,6 @@ func (t *Type) HasTrait(key Trait) bool {
9595
return ok
9696
}
9797

98-
// IsOfType is a type check for errors.
99-
// Returns true either if both are of exactly the same type, or if the same is true for one of current type's ancestors.
100-
// For an error that does not have an errorx type, returns false.
101-
func IsOfType(err error, t *Type) bool {
102-
e := Cast(err)
103-
return e != nil && e.IsOfType(t)
104-
}
105-
10698
// Supertype returns a parent type, if present.
10799
func (t *Type) Supertype() *Type {
108100
return t.parent

0 commit comments

Comments
 (0)