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 }