Add a temporary drop-in replacement for errors.Join

As we have a hard time figuring out what moby/moby#46099 should look
like, this drop-in replacement will solve the initial formatting problem
we have. It's made internal such that we can remove it whenever we want
and unlike moby/moby#46099 doesn't require thoughtful API changes.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Albin Kerouanton 2023-08-10 17:49:00 +02:00
parent 220fba06e7
commit 64de635626
No known key found for this signature in database
GPG key ID: 630B8E1DCBDB1864
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)
})
}