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:
parent
220fba06e7
commit
64de635626
2 changed files with 71 additions and 0 deletions
46
internal/multierror/multierror.go
Normal file
46
internal/multierror/multierror.go
Normal 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
|
||||
}
|
25
internal/multierror/multierror_test.go
Normal file
25
internal/multierror/multierror_test.go
Normal 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)
|
||||
})
|
||||
}
|
Loading…
Reference in a new issue