-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patherrors.go
More file actions
294 lines (264 loc) · 9.7 KB
/
errors.go
File metadata and controls
294 lines (264 loc) · 9.7 KB
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
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
package picker
import (
"errors"
"fmt"
"strings"
)
var (
ErrKindRequired = errors.New("picker: type is required")
ErrUnsupportedType = errors.New("picker: unsupported type")
ErrFieldNotFound = errors.New("picker: field not found")
ErrFieldRequired = errors.New("picker: field is required")
ErrFieldsRequired = errors.New("picker: fields is required")
ErrValueRequired = errors.New("picker: value is required")
ErrQueryRequired = errors.New("picker: query is required")
ErrInvalidSource = errors.New("picker: invalid value for source")
ErrInvalidRewrite = errors.New("picker: invalid value for rewrite")
ErrFieldExists = errors.New("picker: field exists")
ErrPathRequired = errors.New("picker: path is required")
ErrIDRequired = errors.New("picker: id is required")
ErrIndexRequired = errors.New("picker: index is required")
ErrInvalidBoost = errors.New("picker: invalid value for boost")
ErrInvalidFuzzyMaxExpansions = errors.New("picker: invalid value for fuzzy_max_expansions")
ErrInvalidMaxExpansions = errors.New("picker: invalid value for max_expansions")
ErrInvalidPrefixLength = errors.New("picker: invalidvalue for prefix_length")
ErrInvalidZeroTermQuery = errors.New("picker: invalid value for zero_terms_query")
ErrInvalidRelation = errors.New("picker: invalid value for relation")
ErrWeightRequired = errors.New("picker: weight is required")
ErrScriptRequired = errors.New("picker: script is required")
ErrInvalidParams = errors.New("picker: params should marshal into a JSON object")
ErrOriginRequired = errors.New("picker: origin is required")
ErrScaleRequired = errors.New("picker: scale is required")
ErrInvalidScoreMode = errors.New("picker: invalid value for score_mode")
ErrInvalidBoostMode = errors.New("picker: invalid value for boost_mode")
ErrInvalidModifier = errors.New("picker: invalid value for modifier")
ErrMetaLimitExceeded = errors.New("picker: meta limit exceeded")
ErrInvalidDynamic = errors.New("picker: invalid value for dynamic")
ErrInvalidIndexOptions = errors.New("picker: invalid value for index_options")
ErrInvalidIndexPrefixMaxChars = errors.New("picker: invalid value for index prefix_max_chars")
ErrInvalidIndexPrefixMinChars = errors.New("picker: invalid value for index_prefix_min_chars")
ErrScalingFactorRequired = errors.New("picker: scaling_factor is required")
ErrInvalidScalingFactor = errors.New("picker: scaling_factor must be >= 1")
ErrDimensionsRequired = errors.New("picker: dimensions is required")
ErrInvalidOrientation = errors.New("picker: invalid orientation")
ErrInvalidTermVector = errors.New("picker: invalid TermVector")
ErrMissingType = errors.New("picker: missing type")
ErrInvalidMaxShingleSize = errors.New("picker: invalid max_shingle_size; valid values are [2,3,4]")
ErrInvalidNegativeBoost = errors.New("picker: negative_boost must be between 0 and 1.0")
ErrNegativeRequired = errors.New("picker: negative is required")
ErrPositiveRequired = errors.New("picker: positive is required")
ErrQueriesRequired = errors.New("picker: queries is required")
ErrSourceRequired = errors.New("picker: source is required")
ErrPrefixRequired = errors.New("picker: prefix is required")
ErrWildcardRequired = errors.New("picker: wildcard is required")
ErrTermRequired = errors.New("picker: term is required")
ErrTermsRequired = errors.New("picker: terms is required")
ErrValuesRequired = errors.New("picker: values is required")
ErrIntervalsRequired = errors.New("picker: intervals are required")
ErrInvalidOperator = errors.New("picker: invalid operator")
ErrInvalidMultiMatchType = errors.New("picker: invalid multimatch type")
ErrInvalidTieBreaker = errors.New("picker: invalid tie breaker value ")
ErrDistanceRequired = errors.New("picker: distance is required")
ErrGeoPointRequired = errors.New("picker: GeoPoint is required")
ErrLikeRequired = errors.New("picker: like is required")
ErrTypeRequired = errors.New("picker: type is required")
ErrPivotRequired = errors.New("picker: pivot is required")
ErrInvalidPivot = errors.New("picker: pivot must be > 0")
ErrInvalidExponent = errors.New("picker: exponent must be > 0")
ErrExponentRequired = errors.New("picker: exponent is required")
ErrMultiRankFeatureFunctions = errors.New("picker: only one function saturation, log, sigmoid or linear can be provided")
)
type FieldError struct {
Field string
Err error
}
func newFieldError(err error, field string) *FieldError {
var fe *FieldError
if errors.As(err, &fe) {
if fe.Field == field || strings.HasPrefix(field, fe.Field) {
return fe
}
if len(fe.Field) == 0 {
fe.Field = field
} else {
fe.Field = field + "->" + fe.Field
}
return fe
}
return &FieldError{
Field: field,
Err: err,
}
}
func (e *FieldError) Error() string {
return e.Err.Error()
}
func (e *FieldError) Unwrap() error {
return e.Err
}
type QueryError struct {
Field string
Err error
Kind QueryKind
}
func newQueryError(err error, queryKind QueryKind, field ...string) *QueryError {
var f string
if len(field) > 0 {
f = field[0]
}
var qe *QueryError
if errors.As(err, &qe) {
if len(f) != 0 {
qe.Field = f
}
if qe.Kind != queryKind {
qe.Kind = queryKind
}
return qe
}
return &QueryError{
Err: err,
Kind: queryKind,
Field: f,
}
}
func (s QueryError) Error() string {
// TODO: clean this error message up
b := strings.Builder{}
b.WriteString(s.Err.Error())
b.WriteString(" for ")
b.WriteString(s.Kind.String())
if s.Field != "" {
b.WriteString(" <")
b.WriteString(s.Field)
b.WriteRune('>')
}
return b.String()
}
func (s QueryError) Unwrap() error {
return s.Err
}
// Implementation of hashicorp's multierror.
type MappingError struct {
Errors []error
}
func (e *MappingError) assignField(field string) {
if e == nil {
return
}
for i, err := range e.Errors {
var fe *FieldError
if errors.As(err, &fe) {
if len(fe.Field) == 0 {
fe.Field = field
} else if fe.Field != field {
fe.Field = field + "->" + fe.Field
}
} else {
fe = &FieldError{
Field: field,
Err: err,
}
}
e.Errors[i] = fe
}
}
func (e *MappingError) Append(err error) {
if err == nil {
return
}
if merr, ok := err.(*MappingError); ok {
if merr.Errors == nil {
return
}
e.Errors = append(e.Errors, merr.Errors...)
}
e.Errors = append(e.Errors, err)
}
func (e *MappingError) Error() string {
if len(e.Errors) == 1 {
return fmt.Sprintf("1 error occurred:\n\t* %s\n\n", e.Errors[0])
}
points := make([]string, len(e.Errors))
for i, err := range e.Errors {
points[i] = fmt.Sprintf("* %s", err)
}
return fmt.Sprintf(
"%d errors occurred:\n\t%s\n\n",
len(e.Errors), strings.Join(points, "\n\t"))
}
// ErrorOrNil returns an error interface if this Error represents
// a list of errors, or returns nil if the list of errors is empty. This
// function is useful at the end of accumulation to make sure that the value
// returned represents the existence of errors.
func (e *MappingError) ErrorOrNil() error {
if e == nil {
return nil
}
if len(e.Errors) == 0 {
return nil
}
return e
}
func (e *MappingError) GoString() string {
return fmt.Sprintf("*%#v", *e)
}
// WrappedErrors returns the list of errors that this Error is wrapping. It is
// an implementation of the errwrap.Wrapper interface so that multierror.Error
// can be used with that library.
//
// This method is not safe to be called concurrently. Unlike accessing the
// Errors field directly, this function also checks if the multierror is nil to
// prevent a null-pointer panic. It satisfies the errwrap.Wrapper interface.
func (e *MappingError) WrappedErrors() []error {
if e == nil {
return nil
}
return e.Errors
}
// Unwrap returns an error from Error (or nil if there are no errors).
// This error returned will further support Unwrap to get the next error,
// etc. The order will match the order of Errors in the multierror.Error
// at the time of calling.
//
// The resulting error supports errors.As/Is/Unwrap so you can continue
// to use the stdlib errors package to introspect further.
//
// This will perform a shallow copy of the errors slice. Any errors appended
// to this error after calling Unwrap will not be available until a new
// Unwrap is called on the multierror.Error.
func (e *MappingError) Unwrap() error {
// If we have no errors then we do nothing
if e == nil || len(e.Errors) == 0 {
return nil
}
// If we have exactly one error, we can just return that directly.
if len(e.Errors) == 1 {
return e.Errors[0]
}
// Shallow copy the slice
errs := make([]error, len(e.Errors))
copy(errs, e.Errors)
return errorChain(errs)
}
type errorChain []error
// Error implements the error interface
func (e errorChain) Error() string {
return e[0].Error()
}
// Unwrap implements errors.Unwrap by returning the next error in the
// chain or nil if there are no more errors.
func (e errorChain) Unwrap() error {
if len(e) == 1 {
return nil
}
return e[1:]
}
// As implements errors.As by attempting to map to the current value.
func (e errorChain) As(target interface{}) bool {
return errors.As(e[0], target)
}
// Is implements errors.Is by comparing the current value directly.
func (e errorChain) Is(target error) bool {
return errors.Is(e[0], target)
}