Skip to content

Commit e2dfe78

Browse files
committed
Merge branch 'matijavizintin-better-error-handling'
2 parents 5c8d867 + e130aa9 commit e2dfe78

File tree

2 files changed

+28
-13
lines changed

2 files changed

+28
-13
lines changed

parser.go

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,17 @@ import (
99
"unsafe"
1010
)
1111

12+
// Errors
13+
var (
14+
KeyPathNotFoundError = errors.New("Key path not found")
15+
UnknownValueTypeError = errors.New("Unknown value type")
16+
MalformedJsonError = errors.New("Malformed JSON error")
17+
MalformedStringError = errors.New("Value is string, but can't find closing '\"' symbol")
18+
MalformedArrayError = errors.New("Value is array, but can't find closing ']' symbol")
19+
MalformedObjectError = errors.New("Value looks like object, but can't find closing '}' symbol")
20+
MalformedValueError = errors.New("Value looks like Number/Boolean/None, but can't find its end: ',' or '}' symbol")
21+
)
22+
1223
func tokenEnd(data []byte) int {
1324
for i, c := range data {
1425
switch c {
@@ -186,15 +197,15 @@ If no keys provided it will try to extract closest JSON value (simple ones or ob
186197
func Get(data []byte, keys ...string) (value []byte, dataType ValueType, offset int, err error) {
187198
if len(keys) > 0 {
188199
if offset = searchKeys(data, keys...); offset == -1 {
189-
return []byte{}, NotExist, -1, errors.New("Key path not found")
200+
return []byte{}, NotExist, -1, KeyPathNotFoundError
190201
}
191202
}
192203

193204
// Go to closest value
194205
nO := nextToken(data[offset:], false)
195206

196207
if nO == -1 {
197-
return []byte{}, NotExist, -1, errors.New("Malformed JSON error")
208+
return []byte{}, NotExist, -1, MalformedJsonError
198209
}
199210

200211
offset += nO
@@ -206,15 +217,15 @@ func Get(data []byte, keys ...string) (value []byte, dataType ValueType, offset
206217
if idx := stringEnd(data[offset+1:]); idx != -1 {
207218
endOffset += idx + 1
208219
} else {
209-
return []byte{}, dataType, offset, errors.New("Value is string, but can't find closing '\"' symbol")
220+
return []byte{}, dataType, offset, MalformedStringError
210221
}
211222
} else if data[offset] == '[' { // if array value
212223
dataType = Array
213224
// break label, for stopping nested loops
214225
endOffset = blockEnd(data[offset:], '[', ']')
215226

216227
if endOffset == -1 {
217-
return []byte{}, dataType, offset, errors.New("Value is array, but can't find closing ']' symbol")
228+
return []byte{}, dataType, offset, MalformedArrayError
218229
}
219230

220231
endOffset += offset
@@ -224,7 +235,7 @@ func Get(data []byte, keys ...string) (value []byte, dataType ValueType, offset
224235
endOffset = blockEnd(data[offset:], '{', '}')
225236

226237
if endOffset == -1 {
227-
return []byte{}, dataType, offset, errors.New("Value looks like object, but can't find closing '}' symbol")
238+
return []byte{}, dataType, offset, MalformedObjectError
228239
}
229240

230241
endOffset += offset
@@ -233,7 +244,7 @@ func Get(data []byte, keys ...string) (value []byte, dataType ValueType, offset
233244
end := tokenEnd(data[endOffset:])
234245

235246
if end == -1 {
236-
return nil, dataType, offset, errors.New("Value looks like Number/Boolean/None, but can't find its end: ',' or '}' symbol")
247+
return nil, dataType, offset, MalformedValueError
237248
}
238249

239250
value := data[offset : endOffset+end]
@@ -243,18 +254,18 @@ func Get(data []byte, keys ...string) (value []byte, dataType ValueType, offset
243254
if bytes.Equal(value, trueLiteral) || bytes.Equal(value, falseLiteral) {
244255
dataType = Boolean
245256
} else {
246-
return nil, Unknown, offset, errors.New("Unknown value type")
257+
return nil, Unknown, offset, UnknownValueTypeError
247258
}
248259
case 'u', 'n': // undefined or null
249260
if bytes.Equal(value, nullLiteral) {
250261
dataType = Null
251262
} else {
252-
return nil, Unknown, offset, errors.New("Unknown value type")
263+
return nil, Unknown, offset, UnknownValueTypeError
253264
}
254265
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-':
255266
dataType = Number
256267
default:
257-
return nil, Unknown, offset, errors.New("Unknown value type")
268+
return nil, Unknown, offset, UnknownValueTypeError
258269
}
259270

260271
endOffset += end
@@ -277,27 +288,27 @@ func Get(data []byte, keys ...string) (value []byte, dataType ValueType, offset
277288
// ArrayEach is used when iterating arrays, accepts a callback function with the same return arguments as `Get`.
278289
func ArrayEach(data []byte, cb func(value []byte, dataType ValueType, offset int, err error), keys ...string) (err error) {
279290
if len(data) == 0 {
280-
return errors.New("Object is empty")
291+
return MalformedObjectError
281292
}
282293

283294
offset := 1
284295

285296
if len(keys) > 0 {
286297
if offset = searchKeys(data, keys...); offset == -1 {
287-
return errors.New("Key path not found")
298+
return KeyPathNotFoundError
288299
}
289300

290301
// Go to closest value
291302
nO := nextToken(data[offset:], false)
292303

293304
if nO == -1 {
294-
return errors.New("Malformed JSON")
305+
return MalformedJsonError
295306
}
296307

297308
offset += nO
298309

299310
if data[offset] != '[' {
300-
return errors.New("Value is not array")
311+
return MalformedArrayError
301312
}
302313

303314
offset++

parser_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,10 @@ func checkFoundAndNoError(t *testing.T, testKind string, test Test, jtype ValueT
418418
// Else, if the call didn't match the is-found expectation, fail
419419
t.Errorf("%s test '%s' isFound mismatch: expected %t, obtained %t", testKind, test.desc, test.isFound, isFound)
420420
return false
421+
} else if !isFound && err != KeyPathNotFoundError {
422+
// Else, if no value was found and the error is not correct, fail
423+
t.Errorf("%s test '%s' error mismatch: expected %t, obtained %t", testKind, test.desc, KeyPathNotFoundError, err)
424+
return false
421425
} else if !isFound {
422426
// Else, if no value was found, don't fail and don't check the value
423427
return false

0 commit comments

Comments
 (0)