Skip to content

Commit

Permalink
feature: joining errors
Browse files Browse the repository at this point in the history
  • Loading branch information
strider2038 committed Aug 5, 2023
1 parent 7fed68b commit a9df4e7
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 16 deletions.
36 changes: 21 additions & 15 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ func Errorf(message string, argsAndOptions ...interface{}) error {
opts := newOptions(options...)
err := fmt.Errorf(message, args...)

argError := getArgError(message, args)
if isWrapper(argError) {
argErrors := getArgErrors(message, args)
if len(argErrors) == 1 && isWrapper(argErrors[0]) {
return &wrapped{wrapped: err, fields: opts.fields}
}

Expand All @@ -144,12 +144,16 @@ func Wrap(err error, options ...Option) error {
if err == nil {
return nil
}
opts := newOptions(options...)

if isWrapper(err) {
return &wrapped{wrapped: err, fields: opts.fields}
if len(options) == 0 {
return err
}

return &wrapped{wrapped: err, fields: newOptions(options...).fields}
}

opts := newOptions(options...)

return &stacked{
wrapped: &wrapped{wrapped: err, fields: opts.fields},
stack: newStack(opts.skipCallers),
Expand Down Expand Up @@ -278,28 +282,30 @@ func splitArgsAndOptions(argsAndOptions []interface{}) ([]interface{}, []Option)
return args, options
}

func getArgError(message string, args []interface{}) error {
index := getErrorIndex(message)
func getArgErrors(message string, args []interface{}) []error {
indices := getErrorIndices(message)
errs := make([]error, 0, len(indices))

if index >= 0 && index < len(args) {
if err, ok := args[index].(error); ok {
return err
for _, i := range indices {
if err, ok := args[i].(error); ok {
errs = append(errs, err)
}
}

return nil
return errs
}

func getErrorIndex(message string) int {
i := -1
func getErrorIndices(message string) []int {
indices := make([]int, 0, 1)
isFormat := false

i := -1
for _, s := range message {
if isFormat {
if s != '%' {
i++
if s == 'w' {
return i
indices = append(indices, i)
}
}
isFormat = false
Expand All @@ -308,7 +314,7 @@ func getErrorIndex(message string) int {
}
}

return -1
return indices
}

type mapWriter map[string]interface{}
Expand Down
14 changes: 13 additions & 1 deletion errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func TestStackTrace(t *testing.T) {
err: wrap(errors.New("ooh")),
want: []string{
"github.com/muonsoft/errors_test.wrap\n" +
"\t.+/errors/errors_test.go:201",
"\t.+/errors/errors_test.go:213",
"github.com/muonsoft/errors_test.TestStackTrace\n" +
"\t.+/errors/errors_test.go:112",
},
Expand Down Expand Up @@ -181,6 +181,18 @@ func TestStackTrace(t *testing.T) {
"\t.+/errors/errors_test.go:175",
},
},
{
name: "Errorf() with multiple errors",
err: errors.Errorf(
"first: %w; second: %w",
errors.Errorf("ooh"),
errors.Errorf("ooh"),
),
want: []string{
"github.com/muonsoft/errors_test.TestStackTrace\n" +
"\t.+/errors/errors_test.go:186",
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
Expand Down

0 comments on commit a9df4e7

Please sign in to comment.