Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make WalkDeep recursively walk the full chain #73

Merged
merged 3 commits into from
Dec 19, 2024
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
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