github.com/blong14/gache@v0.0.0-20240124023949-89416fd8bbfa/internal/errors/multierror.go (about)

     1  package gerrors
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strings"
     7  )
     8  
     9  type Error struct {
    10  	msg    string
    11  	Errors []error
    12  }
    13  
    14  func (e *Error) Error() string {
    15  	if len(e.Errors) == 1 {
    16  		return fmt.Sprintf("1 error occurred:\n\t* %s\n\n", e.Errors[0])
    17  	}
    18  	points := make([]string, len(e.Errors))
    19  	for i, err := range e.Errors {
    20  		points[i] = fmt.Sprintf("* %s", err)
    21  	}
    22  	return fmt.Sprintf(
    23  		"%d errors occurred:\n\t%s\n\n",
    24  		len(e.Errors), strings.Join(points, "\n\t"))
    25  }
    26  
    27  func (e *Error) ErrorOrNil() error {
    28  	if e == nil {
    29  		return nil
    30  	}
    31  	if len(e.Errors) == 0 {
    32  		return nil
    33  	}
    34  	return e
    35  }
    36  
    37  func (e *Error) GoString() string {
    38  	return fmt.Sprintf("*%#v", *e)
    39  }
    40  
    41  func (e *Error) WrappedErrors() []error {
    42  	if e == nil {
    43  		return nil
    44  	}
    45  	return e.Errors
    46  }
    47  
    48  func (e *Error) Unwrap() error {
    49  	if e == nil || len(e.Errors) == 0 {
    50  		return nil
    51  	}
    52  	if len(e.Errors) == 1 {
    53  		return e.Errors[0]
    54  	}
    55  	errs := make([]error, len(e.Errors))
    56  	copy(errs, e.Errors)
    57  	return chain(errs)
    58  }
    59  
    60  type chain []error
    61  
    62  func (e chain) Error() string {
    63  	return e[0].Error()
    64  }
    65  
    66  func (e chain) Unwrap() error {
    67  	if len(e) == 1 {
    68  		return nil
    69  	}
    70  	return e[1:]
    71  }
    72  
    73  func (e chain) As(target interface{}) bool {
    74  	return errors.As(e[0], target)
    75  }
    76  
    77  func (e chain) Is(target error) bool {
    78  	return errors.Is(e[0], target)
    79  }
    80  
    81  func NewGError(e error) *Error {
    82  	return &Error{
    83  		msg:    e.Error(),
    84  		Errors: []error{e},
    85  	}
    86  }
    87  
    88  func Append(err error, errs ...error) *Error {
    89  	switch err := err.(type) {
    90  	case *Error:
    91  		if err == nil {
    92  			err = new(Error)
    93  		}
    94  		for _, e := range errs {
    95  			switch e := e.(type) {
    96  			case *Error:
    97  				if e != nil {
    98  					err.Errors = append(err.Errors, e.Errors...)
    99  				}
   100  			default:
   101  				if e != nil {
   102  					err.Errors = append(err.Errors, e)
   103  				}
   104  			}
   105  		}
   106  		return err
   107  	default:
   108  		newErrs := make([]error, 0, len(errs)+1)
   109  		if err != nil {
   110  			newErrs = append(newErrs, err)
   111  		}
   112  		newErrs = append(newErrs, errs...)
   113  		return Append(&Error{}, newErrs...)
   114  	}
   115  }
   116  
   117  func OnlyError(_ interface{}, err error) *Error {
   118  	return Append(err)
   119  }