forked from hyperledger-archives/burrow
-
Notifications
You must be signed in to change notification settings - Fork 0
/
errors.go
157 lines (140 loc) · 3.47 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
package errors
import (
"encoding/json"
"fmt"
)
type CodedError interface {
error
ErrorCode() Code
}
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
)
func (c Code) ErrorCode() Code {
return c
}
func (c Code) Error() 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 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 ErrorCodeGeneric:
return "Generic error"
default:
return "Unknown error"
}
}
func NewCodedError(errorCode Code, exception string) *Exception {
if exception == "" {
return nil
}
return &Exception{
Code: &ErrorCode{
Code: uint32(errorCode),
},
Exception: exception,
}
}
// Wraps any error as a Exception
func AsCodedError(err error) *Exception {
if err == nil {
return nil
}
switch e := err.(type) {
case *Exception:
return e
case CodedError:
return NewCodedError(e.ErrorCode(), e.Error())
default:
return NewCodedError(ErrorCodeGeneric, err.Error())
}
}
func Wrap(err CodedError, message string) *Exception {
return NewCodedError(err.ErrorCode(), message+": "+err.Error())
}
func Errorf(format string, a ...interface{}) CodedError {
return ErrorCodef(ErrorCodeGeneric, format, a...)
}
func ErrorCodef(errorCode Code, format string, a ...interface{}) CodedError {
return NewCodedError(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 Code(e.GetCode().Code)
}
func (e *Exception) Error() string {
if e == nil {
return ""
}
return fmt.Sprintf("Error %v: %s", e.Code.Code, e.Exception)
}
func NewErrorCode(code Code) *ErrorCode {
return &ErrorCode{
Code: uint32(code),
}
}
func (e ErrorCode) MarshalJSON() ([]byte, error) {
return json.Marshal(e.Code)
}
func (e *ErrorCode) UnmarshalJSON(bs []byte) error {
return json.Unmarshal(bs, &(e.Code))
}