Skip to content

Commit 0fe6347

Browse files
j2gg0sgopherbot
authored andcommitted
encoding/json: add embedded structs to the UnmarshalTypeError's Field
Including embedded struct inforamtion in error message. Fixes #68941 Change-Id: I6a6f7d506104839a9a7cf1a2c3003272f5534a79 GitHub-Last-Rev: 717f680 GitHub-Pull-Request: #68966 Reviewed-on: https://go-review.googlesource.com/c/go/+/606956 LUCI-TryBot-Result: Go LUCI <[email protected]> Auto-Submit: Ian Lance Taylor <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]>
1 parent 3da6c94 commit 0fe6347

3 files changed

Lines changed: 27 additions & 7 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[UnmarshalTypeError.Field] now includes embedded structs to provide more detailed error messages.

src/encoding/json/decode.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ type UnmarshalTypeError struct {
127127
Type reflect.Type // type of Go value it could not be assigned to
128128
Offset int64 // error occurred after reading Offset bytes
129129
Struct string // name of the struct type containing the field
130-
Field string // the full path from root node to the field
130+
Field string // the full path from root node to the field, include embedded struct
131131
}
132132

133133
func (e *UnmarshalTypeError) Error() string {
@@ -701,7 +701,10 @@ func (d *decodeState) object(v reflect.Value) error {
701701
if f != nil {
702702
subv = v
703703
destring = f.quoted
704-
for _, i := range f.index {
704+
if d.errorContext == nil {
705+
d.errorContext = new(errorContext)
706+
}
707+
for i, ind := range f.index {
705708
if subv.Kind() == reflect.Pointer {
706709
if subv.IsNil() {
707710
// If a struct embeds a pointer to an unexported type,
@@ -721,13 +724,16 @@ func (d *decodeState) object(v reflect.Value) error {
721724
}
722725
subv = subv.Elem()
723726
}
724-
subv = subv.Field(i)
725-
}
726-
if d.errorContext == nil {
727-
d.errorContext = new(errorContext)
727+
if i < len(f.index)-1 {
728+
d.errorContext.FieldStack = append(
729+
d.errorContext.FieldStack,
730+
subv.Type().Field(ind).Name,
731+
)
732+
}
733+
subv = subv.Field(ind)
728734
}
729-
d.errorContext.FieldStack = append(d.errorContext.FieldStack, f.name)
730735
d.errorContext.Struct = t
736+
d.errorContext.FieldStack = append(d.errorContext.FieldStack, f.name)
731737
} else if d.disallowUnknownFields {
732738
d.saveError(fmt.Errorf("json: unknown field %q", key))
733739
}

src/encoding/json/decode_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,19 @@ var unmarshalTests = []struct {
898898
},
899899
},
900900

901+
{
902+
CaseName: Name(""),
903+
in: `{"Level1a": "hello"}`,
904+
ptr: new(Top),
905+
err: &UnmarshalTypeError{
906+
Value: "string",
907+
Struct: "Top",
908+
Field: "Embed0a.Level1a",
909+
Type: reflect.TypeFor[int](),
910+
Offset: 10,
911+
},
912+
},
913+
901914
// issue 15146.
902915
// invalid inputs in wrongStringTests below.
903916
{CaseName: Name(""), in: `{"B":"true"}`, ptr: new(B), out: B{true}, golden: true},

0 commit comments

Comments
 (0)