-
Notifications
You must be signed in to change notification settings - Fork 2
/
error.go
238 lines (190 loc) · 5.13 KB
/
error.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
package multiraftbase
import (
"fmt"
)
type ErrorDetailInterface interface {
error
// message returns an error message.
message(*Error) string
}
type internalError Error
func (e *internalError) Error() string {
return (*Error)(e).String()
}
func (e *internalError) message(_ *Error) string {
return (*Error)(e).String()
}
// String implements fmt.Stringer.
func (e *Error) String() string {
if e == nil {
return "<nil>"
}
return e.Message
}
// NewError creates an Error from the given error.
func NewError(err error) *Error {
if err == nil {
return nil
}
e := &Error{}
if intErr, ok := err.(*internalError); ok {
*e = *(*Error)(intErr)
} else {
e.setGoError(err)
}
return e
}
// NewErrorf creates an Error from the given error message. It is a
// passthrough to fmt.Errorf, with an additional prefix containing the
// filename and line number.
func NewErrorf(format string, a ...interface{}) *Error {
// Cannot use errors.Errorf here due to cyclic dependency.
s := "caller"
return NewError(fmt.Errorf(s+format, a...))
}
// GoError returns a Go error converted from Error.
func (e *Error) GoError() error {
if e == nil {
return nil
}
return e.GetDetailType()
}
// setGoError sets Error using err.
func (e *Error) setGoError(err error) {
if e.Message != "" {
panic("cannot re-use roachpb.Error")
}
if sErr, ok := err.(ErrorDetailInterface); ok {
e.Message = sErr.message(e)
} else {
e.Message = err.Error()
}
// If the specific error type exists in the detail union, set it.
detail := &ErrorDetail{}
if detail.SetValue(err) {
e.Detail = detail
}
return
}
func NewNodeNotReadyError(nodeID NodeID) *NodeNotReadyError {
return &NodeNotReadyError{
NodeID: nodeID,
}
}
func (e *NodeNotReadyError) Error() string {
return e.message(nil)
}
func (e *NodeNotReadyError) message(_ *Error) string {
return fmt.Sprintf("node %s was not ready", e.NodeID)
}
// NewGroupNotFoundError initializes a new GroupNotFoundError.
func NewGroupNotFoundError(groupID GroupID) *GroupNotFoundError {
return &GroupNotFoundError{
GroupID: groupID,
}
}
func (e *GroupNotFoundError) Error() string {
return e.message(nil)
}
func (e *GroupNotFoundError) message(_ *Error) string {
return fmt.Sprintf("r%s was not found", e.GroupID)
}
var _ ErrorDetailInterface = &GroupNotFoundError{}
// NewKeyNonExistent initializes a new KeyNonExistent.
func NewKeyNonExistent(key Key) *KeyNonExistent {
return &KeyNonExistent{
Key: key,
}
}
func (e *KeyNonExistent) Error() string {
return e.message(nil)
}
func (e *KeyNonExistent) message(_ *Error) string {
return fmt.Sprintf("r%s was not found", string(e.Key))
}
var _ ErrorDetailInterface = &KeyNonExistent{}
// NewOnodeBroken initializes a new OnodeBroken.
func NewOnodeBroken(key Key) *OnodeBroken {
return &OnodeBroken{
Key: key,
}
}
func (e *OnodeBroken) Error() string {
return e.message(nil)
}
func (e *OnodeBroken) message(_ *Error) string {
return fmt.Sprintf("onode of %s was broken", string(e.Key))
}
var _ ErrorDetailInterface = &OnodeBroken{}
// NewDataLost initializes a new DataLost.
func NewDataLost(key Key) *DataLost {
return &DataLost{
Key: key,
}
}
func (e *DataLost) Error() string {
return e.message(nil)
}
func (e *DataLost) message(_ *Error) string {
return fmt.Sprintf("data of %s was lost", string(e.Key))
}
var _ ErrorDetailInterface = &DataLost{}
// NewAmbiguousResultError initializes a new AmbiguousResultError with
// an explanatory message.
func NewAmbiguousResultError(msg string) *AmbiguousResultError {
return &AmbiguousResultError{Message: msg}
}
func (e *AmbiguousResultError) Error() string {
return e.message(nil)
}
func (e *AmbiguousResultError) message(_ *Error) string {
return fmt.Sprintf("result is ambiguous (%s)", e.Message)
}
// StoreID is a custom type for a cockroach store ID.
type StoreID int32
// NewStoreNotFoundError initializes a new StoreNotFoundError.
func NewStoreNotFoundError(storeID StoreID) *StoreNotFoundError {
return &StoreNotFoundError{
StoreID: storeID,
}
}
func (e *StoreNotFoundError) Error() string {
return e.message(nil)
}
func (e *StoreNotFoundError) message(_ *Error) string {
return fmt.Sprintf("store %d was not found", e.StoreID)
}
// NewReplicaTooOldError initializes a new ReplicaTooOldError.
func NewReplicaTooOldError(replicaID ReplicaID) *ReplicaTooOldError {
return &ReplicaTooOldError{
ReplicaID: replicaID,
}
}
func (e *ReplicaTooOldError) Error() string {
return e.message(nil)
}
func (*ReplicaTooOldError) message(_ *Error) string {
return "sender replica too old, discarding message"
}
func (e *RaftGroupDeletedError) Error() string {
return e.message(nil)
}
func (*RaftGroupDeletedError) message(_ *Error) string {
return "raft group deleted"
}
var _ ErrorDetailInterface = &RaftGroupDeletedError{}
// GetDetail returns an error detail associated with the error.
func (e *Error) GetDetailType() ErrorDetailInterface {
if e == nil {
return nil
}
if e.Detail == nil {
// Unknown error detail; return the generic error.
return (*internalError)(e)
}
if err, ok := e.Detail.GetValue().(ErrorDetailInterface); ok {
return err
}
// Unknown error detail; return the generic error.
return (*internalError)(e)
}