1
0
mirror of https://github.com/golang/go synced 2024-11-18 00:34:44 -07:00

encoding/json: add Path to UnmarshalTypeError

When parsing nested object, UnmarshalTypeError does not contain actual
path to nested field in original JSON.

This commit change Field to contain the full path to that field. One
can get the Field name by stripping all the leading path elements.

Fixes #22369

Change-Id: I6969cc08abe8387a351e3fb2944adfaa0dccad2a
Reviewed-on: https://go-review.googlesource.com/c/go/+/145218
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
LE Manh Cuong 2018-10-28 01:44:09 +07:00 committed by Daniel Martí
parent 95d4e6158b
commit 29bc4f1258
2 changed files with 28 additions and 4 deletions

View File

@ -125,7 +125,7 @@ type UnmarshalTypeError struct {
Type reflect.Type // type of Go value it could not be assigned to
Offset int64 // error occurred after reading Offset bytes
Struct string // name of the struct type containing the field
Field string // name of the field holding the Go value
Field string // the full path from root node to the field
}
func (e *UnmarshalTypeError) Error() string {
@ -730,7 +730,11 @@ func (d *decodeState) object(v reflect.Value) error {
}
subv = subv.Field(i)
}
d.errorContext.Field = f.name
if originalErrorContext.Field == "" {
d.errorContext.Field = f.name
} else {
d.errorContext.Field = originalErrorContext.Field + "." + f.name
}
d.errorContext.Struct = t
} else if d.disallowUnknownFields {
d.saveError(fmt.Errorf("json: unknown field %q", key))

View File

@ -45,6 +45,14 @@ type W struct {
S SS
}
type P struct {
PP PP
}
type PP struct {
T T
}
type SS string
func (*SS) UnmarshalJSON(data []byte) error {
@ -816,7 +824,7 @@ var unmarshalTests = []unmarshalTest{
err: &UnmarshalTypeError{
Value: "string",
Struct: "V",
Field: "F2",
Field: "V.F2",
Type: reflect.TypeOf(int32(0)),
Offset: 20,
},
@ -827,7 +835,7 @@ var unmarshalTests = []unmarshalTest{
err: &UnmarshalTypeError{
Value: "string",
Struct: "V",
Field: "F2",
Field: "V.F2",
Type: reflect.TypeOf(int32(0)),
Offset: 30,
},
@ -923,6 +931,18 @@ var unmarshalTests = []unmarshalTest{
ptr: new(MustNotUnmarshalText),
err: &UnmarshalTypeError{Value: "object", Type: reflect.TypeOf(&MustNotUnmarshalText{}), Offset: 1},
},
// #22369
{
in: `{"PP": {"T": {"Y": "bad-type"}}}`,
ptr: new(P),
err: &UnmarshalTypeError{
Value: "string",
Struct: "T",
Field: "PP.T.Y",
Type: reflect.TypeOf(int(0)),
Offset: 29,
},
},
}
func TestMarshal(t *testing.T) {