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 5package errors 6 7import ( 8 "unsafe" 9) 10 11// Join returns an error that wraps the given errors. 12// Any nil error values are discarded. 13// Join returns nil if every value in errs is nil. 14// The error formats as the concatenation of the strings obtained 15// by calling the Error method of each element of errs, with a newline 16// between each string. 17// 18// A non-nil error returned by Join implements the Unwrap() []error method. 19func Join(errs ...error) error { 20 n := 0 21 for _, err := range errs { 22 if err != nil { 23 n++ 24 } 25 } 26 if n == 0 { 27 return nil 28 } 29 e := &joinError{ 30 errs: make([]error, 0, n), 31 } 32 for _, err := range errs { 33 if err != nil { 34 e.errs = append(e.errs, err) 35 } 36 } 37 return e 38} 39 40type joinError struct { 41 errs []error 42} 43 44func (e *joinError) Error() string { 45 // Since Join returns nil if every value in errs is nil, 46 // e.errs cannot be empty. 47 if len(e.errs) == 1 { 48 return e.errs[0].Error() 49 } 50 51 b := []byte(e.errs[0].Error()) 52 for _, err := range e.errs[1:] { 53 b = append(b, '\n') 54 b = append(b, err.Error()...) 55 } 56 // At this point, b has at least one byte '\n'. 57 return unsafe.String(&b[0], len(b)) 58} 59 60func (e *joinError) Unwrap() []error { 61 return e.errs 62} 63