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