github.com/datachainlab/burrow@v0.25.0/execution/errors/errors.go (about) 1 package errors 2 3 import ( 4 "fmt" 5 ) 6 7 type CodedError interface { 8 error 9 ErrorCode() Code 10 String() string 11 } 12 13 type Provider interface { 14 // Returns the an error if errors occurred some execution or nil if none occurred 15 Error() CodedError 16 } 17 18 type Sink interface { 19 PushError(error) 20 } 21 22 type Code uint32 23 24 const ( 25 ErrorCodeGeneric Code = iota 26 ErrorCodeUnknownAddress 27 ErrorCodeInsufficientBalance 28 ErrorCodeInvalidJumpDest 29 ErrorCodeInsufficientGas 30 ErrorCodeMemoryOutOfBounds 31 ErrorCodeCodeOutOfBounds 32 ErrorCodeInputOutOfBounds 33 ErrorCodeReturnDataOutOfBounds 34 ErrorCodeCallStackOverflow 35 ErrorCodeCallStackUnderflow 36 ErrorCodeDataStackOverflow 37 ErrorCodeDataStackUnderflow 38 ErrorCodeInvalidContract 39 ErrorCodeNativeContractCodeCopy 40 ErrorCodeExecutionAborted 41 ErrorCodeExecutionReverted 42 ErrorCodePermissionDenied 43 ErrorCodeNativeFunction 44 ErrorCodeEventPublish 45 ErrorCodeInvalidString 46 ErrorCodeEventMapping 47 ErrorCodeInvalidAddress 48 ErrorCodeDuplicateAddress 49 ErrorCodeInsufficientFunds 50 ErrorCodeOverpayment 51 ErrorCodeZeroPayment 52 ErrorCodeInvalidSequence 53 ErrorCodeReservedAddress 54 ErrorCodeIllegalWrite 55 ErrorCodeIntegerOverflow 56 ErrorCodeInvalidProposal 57 ErrorCodeExpiredProposal 58 ErrorCodeProposalExecuted 59 ErrorCodeNoInputPermission 60 ErrorCodeInvalidBlockNumber 61 ErrorCodeBlockNumberOutOfRange 62 ErrorCodeAlreadyVoted 63 ) 64 65 func (c Code) ErrorCode() Code { 66 return c 67 } 68 69 func (c Code) Uint32() uint32 { 70 return uint32(c) 71 } 72 73 func (c Code) Error() string { 74 return fmt.Sprintf("Error %d: %s", c, c.String()) 75 } 76 77 func (c Code) String() string { 78 switch c { 79 case ErrorCodeUnknownAddress: 80 return "unknown address" 81 case ErrorCodeInsufficientBalance: 82 return "insufficient balance" 83 case ErrorCodeInvalidJumpDest: 84 return "invalid jump dest" 85 case ErrorCodeInsufficientGas: 86 return "insufficient gas" 87 case ErrorCodeMemoryOutOfBounds: 88 return "memory out of bounds" 89 case ErrorCodeCodeOutOfBounds: 90 return "code out of bounds" 91 case ErrorCodeInputOutOfBounds: 92 return "input out of bounds" 93 case ErrorCodeReturnDataOutOfBounds: 94 return "return data out of bounds" 95 case ErrorCodeCallStackOverflow: 96 return "call stack overflow" 97 case ErrorCodeCallStackUnderflow: 98 return "call stack underflow" 99 case ErrorCodeDataStackOverflow: 100 return "data stack overflow" 101 case ErrorCodeDataStackUnderflow: 102 return "data stack underflow" 103 case ErrorCodeInvalidContract: 104 return "invalid contract" 105 case ErrorCodePermissionDenied: 106 return "permission denied" 107 case ErrorCodeNativeContractCodeCopy: 108 return "tried to copy native contract code" 109 case ErrorCodeExecutionAborted: 110 return "execution aborted" 111 case ErrorCodeExecutionReverted: 112 return "execution reverted" 113 case ErrorCodeNativeFunction: 114 return "native function error" 115 case ErrorCodeEventPublish: 116 return "event publish error" 117 case ErrorCodeInvalidString: 118 return "invalid string" 119 case ErrorCodeEventMapping: 120 return "event mapping error" 121 case ErrorCodeGeneric: 122 return "generic error" 123 case ErrorCodeInvalidAddress: 124 return "invalid address" 125 case ErrorCodeDuplicateAddress: 126 return "duplicate address" 127 case ErrorCodeInsufficientFunds: 128 return "insufficient funds" 129 case ErrorCodeOverpayment: 130 return "overpayment" 131 case ErrorCodeZeroPayment: 132 return "zero payment error" 133 case ErrorCodeInvalidSequence: 134 return "invalid sequence number" 135 case ErrorCodeReservedAddress: 136 return "address is reserved for SNative or internal use" 137 case ErrorCodeIllegalWrite: 138 return "callee attempted to illegally modify state" 139 case ErrorCodeIntegerOverflow: 140 return "integer overflow" 141 case ErrorCodeInvalidProposal: 142 return "proposal is invalid" 143 case ErrorCodeExpiredProposal: 144 return "proposal is expired since sequence number does not match" 145 case ErrorCodeProposalExecuted: 146 return "proposal has already been executed" 147 case ErrorCodeNoInputPermission: 148 return "account has no input permission" 149 case ErrorCodeInvalidBlockNumber: 150 return "invalid block number" 151 case ErrorCodeBlockNumberOutOfRange: 152 return "block number out of range" 153 case ErrorCodeAlreadyVoted: 154 return "vote already registered for this address" 155 default: 156 return "Unknown error" 157 } 158 } 159 160 func NewException(errorCode Code, exception string) *Exception { 161 if exception == "" { 162 return nil 163 } 164 return &Exception{ 165 Code: errorCode, 166 Exception: exception, 167 } 168 } 169 170 // Wraps any error as a Exception 171 func AsException(err error) *Exception { 172 if err == nil { 173 return nil 174 } 175 switch e := err.(type) { 176 case *Exception: 177 return e 178 case CodedError: 179 return NewException(e.ErrorCode(), e.String()) 180 default: 181 return NewException(ErrorCodeGeneric, err.Error()) 182 } 183 } 184 185 func Wrap(err error, message string) *Exception { 186 ex := AsException(err) 187 return NewException(ex.ErrorCode(), message+": "+ex.Error()) 188 } 189 190 func Errorf(format string, a ...interface{}) *Exception { 191 return ErrorCodef(ErrorCodeGeneric, format, a...) 192 } 193 194 func ErrorCodef(errorCode Code, format string, a ...interface{}) *Exception { 195 return NewException(errorCode, fmt.Sprintf(format, a...)) 196 } 197 198 func (e *Exception) AsError() error { 199 // We need to return a bare untyped error here so that err == nil downstream 200 if e == nil { 201 return nil 202 } 203 return e 204 } 205 206 func (e *Exception) ErrorCode() Code { 207 return e.Code 208 } 209 210 func (e *Exception) Error() string { 211 return fmt.Sprintf("error %d - %s: %s", e.Code, e.Code.String(), e.Exception) 212 } 213 214 func (e *Exception) String() string { 215 if e == nil { 216 return "" 217 } 218 return e.Exception 219 } 220 221 func (e *Exception) Equal(ce CodedError) bool { 222 ex := AsException(ce) 223 if e == nil || ex == nil { 224 return e == nil && ex == nil 225 } 226 return e.Code == ex.Code && e.Exception == ex.Exception 227 } 228 229 type singleError struct { 230 CodedError 231 } 232 233 func FirstOnly() *singleError { 234 return &singleError{} 235 } 236 237 func (se *singleError) PushError(err error) { 238 if se.CodedError == nil { 239 // Do our nil dance 240 ex := AsException(err) 241 if ex != nil { 242 se.CodedError = ex 243 } 244 } 245 } 246 247 func (se *singleError) Error() CodedError { 248 return se.CodedError 249 } 250 251 func (se *singleError) Reset() { 252 se.CodedError = nil 253 }