src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/errutil/multi_error.go (about)

     1  package errutil
     2  
     3  import "strings"
     4  
     5  // Multi combines multiple errors into one:
     6  //
     7  //   - If all errors are nil, it returns nil.
     8  //
     9  //   - If there is one non-nil error, it is returned.
    10  //
    11  //   - Otherwise, the return value is an error whose Error methods contain all
    12  //     the messages of all non-nil arguments.
    13  //
    14  // If the input contains any error returned by Multi, such errors are flattened.
    15  // The following two calls return the same value:
    16  //
    17  //	Multi(Multi(err1, err2), Multi(err3, err4))
    18  //	Multi(err1, err2, err3, err4)
    19  func Multi(errs ...error) error {
    20  	var nonNil []error
    21  	for _, err := range errs {
    22  		if err != nil {
    23  			if multi, ok := err.(multiError); ok {
    24  				nonNil = append(nonNil, multi...)
    25  			} else {
    26  				nonNil = append(nonNil, err)
    27  			}
    28  		}
    29  	}
    30  	switch len(nonNil) {
    31  	case 0:
    32  		return nil
    33  	case 1:
    34  		return nonNil[0]
    35  	default:
    36  		return multiError(nonNil)
    37  	}
    38  }
    39  
    40  type multiError []error
    41  
    42  func (me multiError) Error() string {
    43  	var sb strings.Builder
    44  	sb.WriteString("multiple errors: ")
    45  	for i, e := range me {
    46  		if i > 0 {
    47  			sb.WriteString("; ")
    48  		}
    49  		sb.WriteString(e.Error())
    50  	}
    51  	return sb.String()
    52  }