From 299b49bb172e05cbe9315eefe91bb1865580ac97 Mon Sep 17 00:00:00 2001 From: James Shubin Date: Wed, 16 Jul 2025 23:32:37 -0400 Subject: [PATCH] util: errwrap: Add a function for joining This is like the Append function but for a list. --- util/errwrap/errwrap.go | 15 +++++++ util/errwrap/errwrap_test.go | 86 ++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/util/errwrap/errwrap.go b/util/errwrap/errwrap.go index f545366b..06a91150 100644 --- a/util/errwrap/errwrap.go +++ b/util/errwrap/errwrap.go @@ -57,6 +57,21 @@ func Append(reterr, err error) error { return multierror.Append(reterr, err) } +// Join takes a list of errors and combines them into a multierror with Append. +func Join(errs []error) error { + if len(errs) == 0 { + return nil + } + if len(errs) == 1 { + return errs[0] + } + var reterr error + for _, e := range errs { + reterr = Append(reterr, e) + } + return reterr +} + // String returns a string representation of the error. In particular, if the // error is nil, it returns an empty string instead of panicking. func String(err error) string { diff --git a/util/errwrap/errwrap_test.go b/util/errwrap/errwrap_test.go index 568e9ccb..c5b6d7b4 100644 --- a/util/errwrap/errwrap_test.go +++ b/util/errwrap/errwrap_test.go @@ -77,6 +77,92 @@ func TestAppendErr3(t *testing.T) { } } +func TestJoinErr1(t *testing.T) { + if reterr := Join(nil); reterr != nil { + t.Errorf("expected nil result") + } +} + +func TestJoinErr2(t *testing.T) { + if reterr := Join([]error{}); reterr != nil { + t.Errorf("expected nil result") + } +} + +func TestJoinErr3(t *testing.T) { + err := fmt.Errorf("err") + if reterr := Join([]error{err}); reterr != err { + t.Errorf("expected err") + } +} + +func TestJoinErr4(t *testing.T) { + err := fmt.Errorf("err") + if reterr := Join([]error{err, nil}); reterr != err { + t.Errorf("expected err") + } +} + +func TestJoinErr5(t *testing.T) { + err := fmt.Errorf("err") + if reterr := Join([]error{nil, err}); reterr != err { + t.Errorf("expected err") + } +} + +func TestJoinErr6(t *testing.T) { + err1 := fmt.Errorf("err1") + err2 := fmt.Errorf("err2") + if reterr := Join([]error{err1, err2}); reterr.Error() != Append(err1, err2).Error() { + t.Errorf("expected err") + } +} + +func TestJoinErr7(t *testing.T) { + err1 := fmt.Errorf("err1") + err2 := fmt.Errorf("err2") + err3 := fmt.Errorf("err3") + if reterr := Join([]error{err1, err2, err3}); reterr.Error() != Append(err1, Append(err2, err3)).Error() { + t.Errorf("expected err") + } + if reterr := Join([]error{err1, err2, err3}); reterr.Error() != Append(Append(err1, err2), err3).Error() { + t.Errorf("expected err") + } +} + +func TestJoinErr8(t *testing.T) { + err1 := fmt.Errorf("err1") + var err2 error // nil + err3 := fmt.Errorf("err3") + if reterr := Join([]error{err1, err2, err3}); reterr.Error() != Append(err1, Append(err2, err3)).Error() { + t.Errorf("expected err") + } + if reterr := Join([]error{err1, err2, err3}); reterr.Error() != Append(Append(err1, err2), err3).Error() { + t.Errorf("expected err") + } +} + +func TestJoinErr9(t *testing.T) { + var err1 error // nil + var err2 error // nil + err3 := fmt.Errorf("err3") + if reterr := Join([]error{err1, err2, err3}); reterr.Error() != Append(err1, Append(err2, err3)).Error() { + t.Errorf("expected err") + } + if reterr := Join([]error{err1, err2, err3}); reterr.Error() != Append(Append(err1, err2), err3).Error() { + t.Errorf("expected err") + } +} + +func TestJoinErr10(t *testing.T) { + var err1 error // nil + var err2 error // nil + var err3 error // nil + if reterr := Join([]error{err1, err2, err3}); reterr != nil { + t.Errorf("expected nil result") + } +} + func TestString1(t *testing.T) { var err error if String(err) != "" {