Skip to content

Commit

Permalink
feat: add Disjoin
Browse files Browse the repository at this point in the history
  • Loading branch information
jsteenb2 committed Mar 18, 2024
1 parent 6a7afb0 commit c6c0238
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 6 deletions.
17 changes: 17 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,23 @@ func Join(opts ...any) error {
return newJoinE(opts...)
}

// Disjoin separates joined errors.
func Disjoin(err error) []error {
if err == nil {
return nil
}

if stdJoin, ok := err.(interface{ Unwrap() []error }); ok {
return stdJoin.Unwrap()
}

if ej, ok := err.(*joinE); ok {
return ej.errs
}

return nil
}

// Fields returns logging fields for a given error.
func Fields(err error) []any {
if err == nil {
Expand Down
40 changes: 34 additions & 6 deletions join_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package errors_test

import (
stderrors "errors"
"fmt"
"testing"

Expand Down Expand Up @@ -82,24 +83,51 @@ func TestJoin(t *testing.T) {
)
wantFields := []any{
// parent Join error
"kj1", "vj1", "err_kind", "foo", "stack_trace", []string{"github.com/jsteenb2/errors/join_test.go:74[TestJoin.func4]"},
"kj1", "vj1", "err_kind", "foo", "stack_trace", []string{"github.com/jsteenb2/errors/join_test.go:75[TestJoin.func4]"},
// first err
"err_0", []any{"ki1", "vi1", "err_kind", "foo", "stack_trace", []string{"github.com/jsteenb2/errors/join_test.go:75[TestJoin.func4]"}},
"err_0", []any{"ki1", "vi1", "err_kind", "foo", "stack_trace", []string{"github.com/jsteenb2/errors/join_test.go:76[TestJoin.func4]"}},
// third err
"err_2", []any{"ki3", "vi3", "stack_trace", []string{"github.com/jsteenb2/errors/join_test.go:77[TestJoin.func4]"}},
"err_2", []any{"ki3", "vi3", "stack_trace", []string{"github.com/jsteenb2/errors/join_test.go:78[TestJoin.func4]"}},
// fourth err
"err_3", []any{
"stack_trace", []string{"github.com/jsteenb2/errors/join_test.go:78[TestJoin.func4]"},
"err_0", []any{"stack_trace", []string{"github.com/jsteenb2/errors/join_test.go:79[TestJoin.func4]"}},
"stack_trace", []string{"github.com/jsteenb2/errors/join_test.go:79[TestJoin.func4]"},
"err_0", []any{"stack_trace", []string{"github.com/jsteenb2/errors/join_test.go:80[TestJoin.func4]"}},
},
}
eqFields(t, wantFields, errors.Fields(err))

unwrapped := errors.Unwrap(err)
wantFields = []any{"ki1", "vi1", "err_kind", "foo", "stack_trace", []string{"github.com/jsteenb2/errors/join_test.go:75[TestJoin.func4]"}}
wantFields = []any{"ki1", "vi1", "err_kind", "foo", "stack_trace", []string{"github.com/jsteenb2/errors/join_test.go:76[TestJoin.func4]"}}
eqFields(t, wantFields, errors.Fields(unwrapped))

sentinelUnwrapped := errors.Unwrap(unwrapped)
eqFields(t, nil, errors.Fields(sentinelUnwrapped))
})
}

func TestDisjoin(t *testing.T) {
t.Run("with nil error should return nil", func(t *testing.T) {
errs := errors.Disjoin(nil)
if errs != nil {
t.Fatalf("unexpected errs returned:\n\t\tgot:\t%#v", errs)
}
})

t.Run("with std errors joined errors should unwrap", func(t *testing.T) {
innerErr := fmt.Errorf("simple err")

errs := errors.Disjoin(stderrors.Join(innerErr))

must(t, eqLen(t, 1, errs))
eq(t, innerErr, errs[0])
})

t.Run("with Join error should unwrap", func(t *testing.T) {
innerErr := fmt.Errorf("simple err")

errs := errors.Disjoin(errors.Join(innerErr))

must(t, eqLen(t, 1, errs))
eq(t, innerErr, errs[0])
})
}

0 comments on commit c6c0238

Please sign in to comment.