Merge pull request #46188 from akerouanton/custom-multierror

Add a temporary drop-in replacement for errors.Join
This commit is contained in:
Sebastiaan van Stijn 2023-08-16 17:16:09 +02:00 committed by GitHub
commit d83ead8434
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 0 deletions

View file

@ -0,0 +1,46 @@
package multierror
import (
"strings"
)
// Join is a drop-in replacement for errors.Join with better formatting.
func Join(errs ...error) error {
n := 0
for _, err := range errs {
if err != nil {
n++
}
}
if n == 0 {
return nil
}
e := &joinError{
errs: make([]error, 0, n),
}
for _, err := range errs {
if err != nil {
e.errs = append(e.errs, err)
}
}
return e
}
type joinError struct {
errs []error
}
func (e *joinError) Error() string {
if len(e.errs) == 1 {
return strings.TrimSpace(e.errs[0].Error())
}
stringErrs := make([]string, 0, len(e.errs))
for _, subErr := range e.errs {
stringErrs = append(stringErrs, strings.Replace(subErr.Error(), "\n", "\n\t", -1))
}
return "* " + strings.Join(stringErrs, "\n* ")
}
func (e *joinError) Unwrap() []error {
return e.errs
}

View file

@ -0,0 +1,25 @@
package multierror
import (
"errors"
"fmt"
"testing"
"gotest.tools/v3/assert"
)
func TestErrorJoin(t *testing.T) {
t.Run("single", func(t *testing.T) {
err := Join(fmt.Errorf("invalid config: %w", Join(errors.New("foo"))))
const expected = `invalid config: foo`
assert.Equal(t, err.Error(), expected)
})
t.Run("multiple", func(t *testing.T) {
err := Join(errors.New("foobar"), fmt.Errorf("invalid config: \n%w", Join(errors.New("foo"), errors.New("bar"))))
const expected = `* foobar
* invalid config:
* foo
* bar`
assert.Equal(t, err.Error(), expected)
})
}