pkg.re/essentialkaos/ek.10@v12.41.0+incompatible/errutil/errutil.go (about) 1 // Package errutil provides methods for working with errors 2 package errutil 3 4 // ////////////////////////////////////////////////////////////////////////////////// // 5 // // 6 // Copyright (c) 2022 ESSENTIAL KAOS // 7 // Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0> // 8 // // 9 // ////////////////////////////////////////////////////////////////////////////////// // 10 11 import ( 12 "errors" 13 ) 14 15 // ////////////////////////////////////////////////////////////////////////////////// // 16 17 // Errors is struct for handling many errors at once 18 type Errors struct { 19 capacity int 20 errors []error 21 } 22 23 // ////////////////////////////////////////////////////////////////////////////////// // 24 25 // NewErrors creates new struct 26 func NewErrors(capacity ...int) *Errors { 27 if len(capacity) == 0 { 28 return &Errors{} 29 } 30 31 size := capacity[0] 32 33 if size < 0 { 34 size = 0 35 } 36 37 return &Errors{capacity: size} 38 } 39 40 // Chain executes functions in chain and if one of them return error 41 // this function stop chain execution and return this error 42 func Chain(funcs ...func() error) error { 43 var err error 44 45 for _, fc := range funcs { 46 err = fc() 47 48 if err != nil { 49 return err 50 } 51 } 52 53 return err 54 } 55 56 // ////////////////////////////////////////////////////////////////////////////////// // 57 58 // Add adds new error to slice 59 func (e *Errors) Add(errs ...interface{}) *Errors { 60 if errs == nil { 61 return e 62 } 63 64 for _, err := range errs { 65 switch v := err.(type) { 66 case *Errors: 67 if v != nil { 68 e.errors = append(e.errors, v.errors...) 69 } 70 case Errors: 71 e.errors = append(e.errors, v.errors...) 72 case []error: 73 e.errors = append(e.errors, v...) 74 case []string: 75 for _, s := range v { 76 e.errors = append(e.errors, errors.New(s)) 77 } 78 case error: 79 e.errors = append(e.errors, v) 80 case string: 81 e.errors = append(e.errors, errors.New(v)) 82 } 83 } 84 85 if e.capacity > 0 && len(e.errors) > e.capacity { 86 e.errors = e.errors[len(e.errors)-e.capacity:] 87 } 88 89 return e 90 } 91 92 // Last returns the last error 93 func (e *Errors) Last() error { 94 if e == nil || e.errors == nil { 95 return nil 96 } 97 98 return e.errors[len(e.errors)-1] 99 } 100 101 // All returns all errors in slice 102 func (e *Errors) All() []error { 103 if e == nil || e.errors == nil { 104 return nil 105 } 106 107 return e.errors 108 } 109 110 // HasErrors checks if slice contains errors 111 func (e *Errors) HasErrors() bool { 112 if e == nil || e.errors == nil { 113 return false 114 } 115 116 return len(e.errors) != 0 117 } 118 119 // Num returns number of errors 120 func (e *Errors) Num() int { 121 if e == nil { 122 return 0 123 } 124 125 return len(e.errors) 126 } 127 128 // Cap returns max capacity 129 func (e *Errors) Cap() int { 130 if e == nil { 131 return 0 132 } 133 134 return e.capacity 135 } 136 137 // Error returns text of all errors 138 func (e *Errors) Error() string { 139 if e == nil || len(e.errors) == 0 { 140 return "" 141 } 142 143 var result string 144 145 for _, err := range e.errors { 146 result += " " + err.Error() + "\n" 147 } 148 149 return result 150 } 151 152 // Reset resets Errors instance to be empty 153 func (e *Errors) Reset() { 154 e.errors = nil 155 }