Skip to content

Commit 8e69c81

Browse files
committed
Add a specific error type for unmarshaling errors
1 parent 2bec2bb commit 8e69c81

File tree

2 files changed

+33
-13
lines changed

2 files changed

+33
-13
lines changed

decoder.go

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package maxminddb
22

33
import (
44
"encoding/binary"
5-
"fmt"
65
"math"
76
"math/big"
87
"reflect"
@@ -126,7 +125,7 @@ func (d *decoder) unmarshalBool(size uint, offset uint, result reflect.Value) (u
126125
}
127126
switch result.Kind() {
128127
default:
129-
return newOffset, fmt.Errorf("trying to unmarshal %v into %v", value, result.Type())
128+
return newOffset, newUnmarshalTypeError(value, result.Type())
130129
case reflect.Bool:
131130
result.SetBool(value)
132131
return newOffset, nil
@@ -144,7 +143,7 @@ func (d *decoder) unmarshalBytes(size uint, offset uint, result reflect.Value) (
144143
}
145144
switch result.Kind() {
146145
default:
147-
return newOffset, fmt.Errorf("trying to unmarshal %v into %v", value, result.Type())
146+
return newOffset, newUnmarshalTypeError(value, result.Type())
148147
case reflect.Slice:
149148
result.SetBytes(value)
150149
return newOffset, nil
@@ -165,7 +164,7 @@ func (d *decoder) unmarshalFloat32(size uint, offset uint, result reflect.Value)
165164

166165
switch result.Kind() {
167166
default:
168-
return newOffset, fmt.Errorf("trying to unmarshal %v into %v", value, result.Type())
167+
return newOffset, newUnmarshalTypeError(value, result.Type())
169168
case reflect.Float32, reflect.Float64:
170169
result.SetFloat(float64(value))
171170
return newOffset, nil
@@ -186,7 +185,7 @@ func (d *decoder) unmarshalFloat64(size uint, offset uint, result reflect.Value)
186185
}
187186
switch result.Kind() {
188187
default:
189-
return newOffset, fmt.Errorf("trying to unmarshal %v into %v", value, result.Type())
188+
return newOffset, newUnmarshalTypeError(value, result.Type())
190189
case reflect.Float32, reflect.Float64:
191190
result.SetFloat(value)
192191
return newOffset, nil
@@ -207,13 +206,13 @@ func (d *decoder) unmarshalInt32(size uint, offset uint, result reflect.Value) (
207206

208207
switch result.Kind() {
209208
default:
210-
return newOffset, fmt.Errorf("trying to unmarshal %v into %v", value, result.Type())
209+
return newOffset, newUnmarshalTypeError(value, result.Type())
211210
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
212211
result.SetInt(int64(value))
213212
return newOffset, nil
214213
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
215214
if value < 0 {
216-
return 0, fmt.Errorf("trying to unmarshal %v into %v", value, result.Type())
215+
return 0, newUnmarshalTypeError(value, result.Type())
217216
}
218217
result.SetUint(uint64(value))
219218
return newOffset, nil
@@ -226,7 +225,7 @@ func (d *decoder) unmarshalInt32(size uint, offset uint, result reflect.Value) (
226225
func (d *decoder) unmarshalMap(size uint, offset uint, result reflect.Value) (uint, error) {
227226
switch result.Kind() {
228227
default:
229-
return 0, fmt.Errorf("trying to unmarshal a map into %v", result.Type())
228+
return 0, newUnmarshalTypeError("map", result.Type())
230229
case reflect.Struct:
231230
return d.decodeStruct(size, offset, result)
232231
case reflect.Map:
@@ -249,7 +248,7 @@ func (d *decoder) unmarshalSlice(size uint, offset uint, result reflect.Value) (
249248

250249
switch result.Kind() {
251250
default:
252-
return 0, fmt.Errorf("trying to unmarshal an array into %v", result.Type())
251+
return 0, newUnmarshalTypeError("array", result.Type())
253252
case reflect.Slice:
254253
return d.decodeSlice(size, offset, result)
255254
case reflect.Interface:
@@ -270,7 +269,7 @@ func (d *decoder) unmarshalString(size uint, offset uint, result reflect.Value)
270269
}
271270
switch result.Kind() {
272271
default:
273-
return newOffset, fmt.Errorf("trying to unmarshal %v into %v", value, result.Type())
272+
return newOffset, newUnmarshalTypeError(value, result.Type())
274273
case reflect.String:
275274
result.SetString(value)
276275
return newOffset, nil
@@ -292,7 +291,7 @@ func (d *decoder) unmarshalUint(size uint, offset uint, result reflect.Value, ui
292291

293292
switch result.Kind() {
294293
default:
295-
return newOffset, fmt.Errorf("trying to unmarshal %v into %v", value, result.Type())
294+
return newOffset, newUnmarshalTypeError(value, result.Type())
296295
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
297296
result.SetInt(int64(value))
298297
return newOffset, nil
@@ -318,7 +317,7 @@ func (d *decoder) unmarshalUint128(size uint, offset uint, result reflect.Value)
318317
// Currently this is reported as invalid
319318
switch result.Kind() {
320319
default:
321-
return newOffset, fmt.Errorf("trying to unmarshal %v into %v", value, result.Type())
320+
return newOffset, newUnmarshalTypeError(value, result.Type())
322321
case reflect.Struct:
323322
result.Set(reflect.ValueOf(*value))
324323
return newOffset, nil

errors.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package maxminddb
22

3-
import "fmt"
3+
import (
4+
"fmt"
5+
"reflect"
6+
)
47

58
// InvalidDatabaseError is returned when the database contains invalid data
69
// and cannot be parsed.
@@ -15,3 +18,21 @@ func newInvalidDatabaseError(format string, args ...interface{}) InvalidDatabase
1518
func (e InvalidDatabaseError) Error() string {
1619
return e.message
1720
}
21+
22+
// UnmarshalTypeError is returned when the value in the database cannot be
23+
// assigned to the specified data type.
24+
type UnmarshalTypeError struct {
25+
Value string // stringified copy of the database value that caused the error
26+
Type reflect.Type // type of the value that could not be assign to
27+
}
28+
29+
func newUnmarshalTypeError(value interface{}, rType reflect.Type) UnmarshalTypeError {
30+
return UnmarshalTypeError{
31+
Value: fmt.Sprintf("%v", value),
32+
Type: rType,
33+
}
34+
}
35+
36+
func (e UnmarshalTypeError) Error() string {
37+
return fmt.Sprintf("maxminddb: cannot unmarshal %s into type %s", e.Value, e.Type.String())
38+
}

0 commit comments

Comments
 (0)