Skip to content

Commit

Permalink
make WalkDeep recursively walk the full chain (#73)
Browse files Browse the repository at this point in the history
* make `WalkDeep` recursively walk the full chain
  • Loading branch information
YuJuncen authored Dec 19, 2024
1 parent b352690 commit 6b8c588
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 4 deletions.
47 changes: 47 additions & 0 deletions errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,53 @@ func TestWalkDeep(t *testing.T) {
}
}

func TestWalkDeepNil(t *testing.T) {
require.False(t, WalkDeep(nil, func(err error) bool { return true }))
}

func TestWalkDeepComplexTree(t *testing.T) {
err := &errWalkTest{v: 1, cause: &errWalkTest{
sub: []error{
&errWalkTest{
v: 10,
cause: &errWalkTest{v: 11},
},
&errWalkTest{
v: 20,
sub: []error{
&errWalkTest{v: 21},
&errWalkTest{v: 22},
},
},
&errWalkTest{
v: 30,
cause: &errWalkTest{v: 31},
},
},
}}

assertFind := func(v int, comment string) {
if !testFind(err, v) {
t.Errorf("%d not found in the error: %s", v, comment)
}
}
assertNotFind := func(v int, comment string) {
if testFind(err, v) {
t.Errorf("%d found in the error, but not expected: %s", v, comment)
}
}

assertFind(1, "shallow search")
assertFind(11, "deep search A1")
assertFind(21, "deep search A2")
assertFind(22, "deep search B1")
assertNotFind(23, "deep search Neg")
assertFind(31, "deep search B2")
assertNotFind(32, "deep search Neg")
assertFind(30, "Tree node A")
assertFind(20, "Tree node with many children")
}

type fooError int

func (fooError) Error() string {
Expand Down
15 changes: 11 additions & 4 deletions group.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,20 @@ func Errors(err error) []error {
// The visitor function can return true to end the traversal early
// In that case, WalkDeep will return true, otherwise false.
func WalkDeep(err error, visitor func(err error) bool) bool {
if err == nil {
return false
}

if visitor(err) {
return true
}

// Go deep
unErr := err
for unErr != nil {
if done := visitor(unErr); done {
unErr := Unwrap(err)
if unErr != nil {
if WalkDeep(unErr, visitor) {
return true
}
unErr = Unwrap(unErr)
}

// Go wide
Expand Down

0 comments on commit 6b8c588

Please sign in to comment.