aboutsummaryrefslogtreecommitdiff
path: root/src/errors/wrap_test.go
diff options
context:
space:
mode:
authorDamien Neil <dneil@google.com>2022-09-22 10:43:26 -0700
committerDamien Neil <dneil@google.com>2022-09-29 18:40:40 +0000
commit4a0a2b33dfa3c99250efa222439f2c27d6780e4a (patch)
tree25b1d2541b1b1244fe86d3b7ab690bff475e7ac7 /src/errors/wrap_test.go
parent36f046d934c66fb6eb47d568e04665708c096ad7 (diff)
downloadgo-4a0a2b33dfa3c99250efa222439f2c27d6780e4a.tar.xz
errors, fmt: add support for wrapping multiple errors
An error which implements an "Unwrap() []error" method wraps all the non-nil errors in the returned []error. We replace the concept of the "error chain" inspected by errors.Is and errors.As with the "error tree". Is and As perform a pre-order, depth-first traversal of an error's tree. As returns the first matching result, if any. The new errors.Join function returns an error wrapping a list of errors. The fmt.Errorf function now supports multiple instances of the %w verb. For #53435. Change-Id: Ib7402e70b68e28af8f201d2b66bd8e87ccfb5283 Reviewed-on: https://go-review.googlesource.com/c/go/+/432898 Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Rob Pike <r@golang.org> Run-TryBot: Damien Neil <dneil@google.com> Reviewed-by: Joseph Tsai <joetsai@digital-static.net>
Diffstat (limited to 'src/errors/wrap_test.go')
-rw-r--r--src/errors/wrap_test.go52
1 files changed, 51 insertions, 1 deletions
diff --git a/src/errors/wrap_test.go b/src/errors/wrap_test.go
index eb8314b04b..9efbe45ee0 100644
--- a/src/errors/wrap_test.go
+++ b/src/errors/wrap_test.go
@@ -47,6 +47,17 @@ func TestIs(t *testing.T) {
{&errorUncomparable{}, &errorUncomparable{}, false},
{errorUncomparable{}, err1, false},
{&errorUncomparable{}, err1, false},
+ {multiErr{}, err1, false},
+ {multiErr{err1, err3}, err1, true},
+ {multiErr{err3, err1}, err1, true},
+ {multiErr{err1, err3}, errors.New("x"), false},
+ {multiErr{err3, errb}, errb, true},
+ {multiErr{err3, errb}, erra, true},
+ {multiErr{err3, errb}, err1, true},
+ {multiErr{errb, err3}, err1, true},
+ {multiErr{poser}, err1, true},
+ {multiErr{poser}, err3, true},
+ {multiErr{nil}, nil, false},
}
for _, tc := range testCases {
t.Run("", func(t *testing.T) {
@@ -148,6 +159,41 @@ func TestAs(t *testing.T) {
&timeout,
true,
errF,
+ }, {
+ multiErr{},
+ &errT,
+ false,
+ nil,
+ }, {
+ multiErr{errors.New("a"), errorT{"T"}},
+ &errT,
+ true,
+ errorT{"T"},
+ }, {
+ multiErr{errorT{"T"}, errors.New("a")},
+ &errT,
+ true,
+ errorT{"T"},
+ }, {
+ multiErr{errorT{"a"}, errorT{"b"}},
+ &errT,
+ true,
+ errorT{"a"},
+ }, {
+ multiErr{multiErr{errors.New("a"), errorT{"a"}}, errorT{"b"}},
+ &errT,
+ true,
+ errorT{"a"},
+ }, {
+ multiErr{wrapped{"path error", errF}},
+ &timeout,
+ true,
+ errF,
+ }, {
+ multiErr{nil},
+ &errT,
+ false,
+ nil,
}}
for i, tc := range testCases {
name := fmt.Sprintf("%d:As(Errorf(..., %v), %v)", i, tc.err, tc.target)
@@ -223,9 +269,13 @@ type wrapped struct {
}
func (e wrapped) Error() string { return e.msg }
-
func (e wrapped) Unwrap() error { return e.err }
+type multiErr []error
+
+func (m multiErr) Error() string { return "multiError" }
+func (m multiErr) Unwrap() []error { return []error(m) }
+
type errorUncomparable struct {
f []string
}