| 
									
										
										
										
											2019-03-19 21:31:57 +08:00
										 |  |  | // Copyright 2016 The etcd Authors
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Licensed under the Apache License, Version 2.0 (the "License");
 | 
					
						
							|  |  |  | // you may not use this file except in compliance with the License.
 | 
					
						
							|  |  |  | // You may obtain a copy of the License at
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //     http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Unless required by applicable law or agreed to in writing, software
 | 
					
						
							|  |  |  | // distributed under the License is distributed on an "AS IS" BASIS,
 | 
					
						
							|  |  |  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					
						
							|  |  |  | // See the License for the specific language governing permissions and
 | 
					
						
							|  |  |  | // limitations under the License.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package errors | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2023-03-23 18:10:00 +08:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2019-03-19 21:31:57 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2020-10-28 23:24:58 +08:00
										 |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2019-03-19 21:31:57 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-28 23:24:58 +08:00
										 |  |  | // multiError type allows combining multiple errors into one.
 | 
					
						
							|  |  |  | type multiError []error | 
					
						
							| 
									
										
										
										
											2019-03-19 21:31:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-28 23:24:58 +08:00
										 |  |  | // NewMulti returns multiError with provided errors added if not nil.
 | 
					
						
							| 
									
										
										
										
											2025-03-07 18:28:26 +08:00
										 |  |  | func NewMulti(errs ...error) multiError { //nolint:revive // unexported-return
 | 
					
						
							| 
									
										
										
										
											2020-10-28 23:24:58 +08:00
										 |  |  | 	m := multiError{} | 
					
						
							|  |  |  | 	m.Add(errs...) | 
					
						
							|  |  |  | 	return m | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Add adds single or many errors to the error list. Each error is added only if not nil.
 | 
					
						
							|  |  |  | // If the error is a nonNilMultiError type, the errors inside nonNilMultiError are added to the main multiError.
 | 
					
						
							|  |  |  | func (es *multiError) Add(errs ...error) { | 
					
						
							|  |  |  | 	for _, err := range errs { | 
					
						
							|  |  |  | 		if err == nil { | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-11-15 01:48:53 +08:00
										 |  |  | 		var merr nonNilMultiError | 
					
						
							|  |  |  | 		if errors.As(err, &merr) { | 
					
						
							| 
									
										
										
										
											2020-10-28 23:24:58 +08:00
										 |  |  | 			*es = append(*es, merr.errs...) | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		*es = append(*es, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Err returns the error list as an error or nil if it is empty.
 | 
					
						
							|  |  |  | func (es multiError) Err() error { | 
					
						
							|  |  |  | 	if len(es) == 0 { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nonNilMultiError{errs: es} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // nonNilMultiError implements the error interface, and it represents
 | 
					
						
							|  |  |  | // multiError with at least one error inside it.
 | 
					
						
							|  |  |  | // This type is needed to make sure that nil is returned when no error is combined in multiError for err != nil
 | 
					
						
							|  |  |  | // check to work.
 | 
					
						
							|  |  |  | type nonNilMultiError struct { | 
					
						
							|  |  |  | 	errs multiError | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Error returns a concatenated string of the contained errors.
 | 
					
						
							|  |  |  | func (es nonNilMultiError) Error() string { | 
					
						
							| 
									
										
										
										
											2019-03-19 21:31:57 +08:00
										 |  |  | 	var buf bytes.Buffer | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-28 23:24:58 +08:00
										 |  |  | 	if len(es.errs) > 1 { | 
					
						
							|  |  |  | 		fmt.Fprintf(&buf, "%d errors: ", len(es.errs)) | 
					
						
							| 
									
										
										
										
											2019-03-19 21:31:57 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-28 23:24:58 +08:00
										 |  |  | 	for i, err := range es.errs { | 
					
						
							| 
									
										
										
										
											2019-03-19 21:31:57 +08:00
										 |  |  | 		if i != 0 { | 
					
						
							|  |  |  | 			buf.WriteString("; ") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		buf.WriteString(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return buf.String() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-23 18:10:00 +08:00
										 |  |  | // Is attempts to match the provided error against errors in the error list.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This function allows errors.Is to traverse the values stored in the MultiError.
 | 
					
						
							|  |  |  | // It returns true if any of the errors in the list match the target.
 | 
					
						
							|  |  |  | func (es nonNilMultiError) Is(target error) bool { | 
					
						
							|  |  |  | 	for _, err := range es.errs { | 
					
						
							|  |  |  | 		if errors.Is(err, target) { | 
					
						
							|  |  |  | 			return true | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-06 21:45:16 +08:00
										 |  |  | // Unwrap returns the list of errors contained in the multiError.
 | 
					
						
							|  |  |  | func (es nonNilMultiError) Unwrap() []error { | 
					
						
							|  |  |  | 	return es.errs | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-28 23:24:58 +08:00
										 |  |  | // CloseAll closes all given closers while recording error in MultiError.
 | 
					
						
							|  |  |  | func CloseAll(cs []io.Closer) error { | 
					
						
							|  |  |  | 	errs := NewMulti() | 
					
						
							|  |  |  | 	for _, c := range cs { | 
					
						
							|  |  |  | 		errs.Add(c.Close()) | 
					
						
							| 
									
										
										
										
											2019-03-19 21:31:57 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-10-28 23:24:58 +08:00
										 |  |  | 	return errs.Err() | 
					
						
							| 
									
										
										
										
											2019-03-19 21:31:57 +08:00
										 |  |  | } |