1 // Copyright 2022 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 5 package errors
6 7 import (
8 )
9 10 // Join returns an error that wraps the given errors.
11 // Any nil error values are discarded.
12 // Join returns nil if every value in errs is nil.
13 // The error formats as the concatenation of the strings obtained
14 // by calling the Error method of each element of errs, with a newline
15 // between each string.
16 //
17 // A non-nil error returned by Join implements the Unwrap() []error method.
18 func Join(errs ...error) error {
19 n := 0
20 for _, err := range errs {
21 if err != nil {
22 n++
23 }
24 }
25 if n == 0 {
26 return nil
27 }
28 if n == 1 {
29 for _, err := range errs {
30 if err != nil {
31 if _, ok := err.(interface {
32 Unwrap() []error
33 }); ok {
34 return err
35 }
36 }
37 }
38 }
39 40 e := &joinError{
41 errs: []error{:0:n},
42 }
43 for _, err := range errs {
44 if err != nil {
45 e.errs = append(e.errs, err)
46 }
47 }
48 return e
49 }
50 51 type joinError struct {
52 errs []error
53 }
54 55 func (e *joinError) Error() string {
56 // Since Join returns nil if every value in errs is nil,
57 // e.errs cannot be empty.
58 if len(e.errs) == 1 {
59 return e.errs[0].Error()
60 }
61 62 b := []byte(e.errs[0].Error())
63 for _, err := range e.errs[1:] {
64 b = append(b, '\n')
65 b = append(b, err.Error()...)
66 }
67 // At this point, b has at least one byte '\n'.
68 return string(b)
69 }
70 71 func (e *joinError) Unwrap() []error {
72 return e.errs
73 }
74