diff options
Diffstat (limited to 'src/encoding/json/v2_decode.go')
| -rw-r--r-- | src/encoding/json/v2_decode.go | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/src/encoding/json/v2_decode.go b/src/encoding/json/v2_decode.go index 1041ec7ee4..f17d7ebcca 100644 --- a/src/encoding/json/v2_decode.go +++ b/src/encoding/json/v2_decode.go @@ -14,6 +14,7 @@ import ( "fmt" "reflect" "strconv" + "strings" "encoding/json/internal/jsonwire" "encoding/json/jsontext" @@ -119,7 +120,20 @@ type UnmarshalTypeError struct { func (e *UnmarshalTypeError) Error() string { var s string if e.Struct != "" || e.Field != "" { - s = "json: cannot unmarshal " + e.Value + " into Go struct field " + e.Struct + "." + e.Field + " of type " + e.Type.String() + // The design of UnmarshalTypeError overly assumes a struct-based + // Go representation for the JSON value. + // The logic in jsontext represents paths using a JSON Pointer, + // which is agnostic to the Go type system. + // Trying to convert a JSON Pointer into a UnmarshalTypeError.Field + // is difficult. As a heuristic, if the last path token looks like + // an index into a JSON array (e.g., ".foo.bar.0"), + // avoid the phrase "Go struct field ". + intoWhat := "Go struct field " + i := strings.LastIndexByte(e.Field, '.') + len(".") + if len(e.Field[i:]) > 0 && strings.TrimRight(e.Field[i:], "0123456789") == "" { + intoWhat = "" // likely a Go slice or array + } + s = "json: cannot unmarshal " + e.Value + " into " + intoWhat + e.Struct + "." + e.Field + " of type " + e.Type.String() } else { s = "json: cannot unmarshal " + e.Value + " into Go value of type " + e.Type.String() } |
