70 lines
1.7 KiB
Go
70 lines
1.7 KiB
Go
|
package errors
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
// MultiError is an error combining multiple other errors.
|
||
|
// It will never have 0 or 1 errors. It will always have two or more.
|
||
|
type MultiError struct {
|
||
|
errs []error
|
||
|
}
|
||
|
|
||
|
// FlattenErrors possibly creates a MultiError.
|
||
|
// Nil entries are ignored.
|
||
|
// If all provided errors are nil (or nothing is provided), nil is returned.
|
||
|
// If only one non-nil error is provided, it is returned unchanged.
|
||
|
// If two or more non-nil errors are provided, the returned error will be of type *MultiError
|
||
|
// and it will contain each non-nil error.
|
||
|
func FlattenErrors(errs ...error) error {
|
||
|
rv := MultiError{}
|
||
|
for _, err := range errs {
|
||
|
if err != nil {
|
||
|
if merr, isMerr := err.(*MultiError); isMerr {
|
||
|
rv.errs = append(rv.errs, merr.errs...)
|
||
|
} else {
|
||
|
rv.errs = append(rv.errs, err)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
switch rv.Len() {
|
||
|
case 0:
|
||
|
return nil
|
||
|
case 1:
|
||
|
return rv.errs[0]
|
||
|
}
|
||
|
return &rv
|
||
|
}
|
||
|
|
||
|
// GetErrors gets all the errors that make up this MultiError.
|
||
|
func (e MultiError) GetErrors() []error {
|
||
|
// Return a copy of the errs slice to prevent alteration of the original slice.
|
||
|
rv := make([]error, e.Len())
|
||
|
copy(rv, e.errs)
|
||
|
return rv
|
||
|
}
|
||
|
|
||
|
// Len gets the number of errors in this MultiError.
|
||
|
func (e MultiError) Len() int {
|
||
|
return len(e.errs)
|
||
|
}
|
||
|
|
||
|
// Error implements the error interface for a MultiError.
|
||
|
func (e *MultiError) Error() string {
|
||
|
var sb strings.Builder
|
||
|
sb.WriteString(fmt.Sprintf("%d errors: ", len(e.errs)))
|
||
|
for i, err := range e.errs {
|
||
|
if i != 0 {
|
||
|
sb.WriteString(", ")
|
||
|
}
|
||
|
sb.WriteString(fmt.Sprintf("%d: %v", i+1, err))
|
||
|
}
|
||
|
return sb.String()
|
||
|
}
|
||
|
|
||
|
// String implements the string interface for a MultiError.
|
||
|
func (e MultiError) String() string {
|
||
|
return e.Error()
|
||
|
}
|