@@ -112,9 +112,14 @@ type UnmarshalTypeError struct {
112112 Value string // description of JSON value - "bool", "array", "number -5"
113113 Type reflect.Type // type of Go value it could not be assigned to
114114 Offset int64 // error occurred after reading Offset bytes
115+ Struct string // name of the struct type containing the field
116+ Field string // name of the field holding the Go value
115117}
116118
117119func (e * UnmarshalTypeError ) Error () string {
120+ if e .Struct != "" || e .Field != "" {
121+ return "json: cannot unmarshal " + e .Value + " into Go struct field " + e .Struct + "." + e .Field + " of type " + e .Type .String ()
122+ }
118123 return "json: cannot unmarshal " + e .Value + " into Go value of type " + e .Type .String ()
119124}
120125
@@ -248,10 +253,14 @@ func isValidNumber(s string) bool {
248253
249254// decodeState represents the state while decoding a JSON value.
250255type decodeState struct {
251- data []byte
252- off int // read offset in data
253- scan scanner
254- nextscan scanner // for calls to nextValue
256+ data []byte
257+ off int // read offset in data
258+ scan scanner
259+ nextscan scanner // for calls to nextValue
260+ errorContext struct { // provides context for type errors
261+ Struct string
262+ Field string
263+ }
255264 savedError error
256265 useNumber bool
257266}
@@ -265,22 +274,37 @@ func (d *decodeState) init(data []byte) *decodeState {
265274 d .data = data
266275 d .off = 0
267276 d .savedError = nil
277+ d .errorContext .Struct = ""
278+ d .errorContext .Field = ""
268279 return d
269280}
270281
271282// error aborts the decoding by panicking with err.
272283func (d * decodeState ) error (err error ) {
273- panic (err )
284+ panic (d . addErrorContext ( err ) )
274285}
275286
276287// saveError saves the first err it is called with,
277288// for reporting at the end of the unmarshal.
278289func (d * decodeState ) saveError (err error ) {
279290 if d .savedError == nil {
280- d .savedError = err
291+ d .savedError = d . addErrorContext ( err )
281292 }
282293}
283294
295+ // addErrorContext returns a new error enhanced with information from d.errorContext
296+ func (d * decodeState ) addErrorContext (err error ) error {
297+ if d .errorContext .Struct != "" || d .errorContext .Field != "" {
298+ switch err := err .(type ) {
299+ case * UnmarshalTypeError :
300+ err .Struct = d .errorContext .Struct
301+ err .Field = d .errorContext .Field
302+ return err
303+ }
304+ }
305+ return err
306+ }
307+
284308// next cuts off and returns the next full JSON value in d.data[d.off:].
285309// The next value is known to be an object or array, not a literal.
286310func (d * decodeState ) next () []byte {
@@ -457,7 +481,7 @@ func (d *decodeState) array(v reflect.Value) {
457481 return
458482 }
459483 if ut != nil {
460- d .saveError (& UnmarshalTypeError {"array" , v .Type (), int64 (d .off )})
484+ d .saveError (& UnmarshalTypeError {Value : "array" , Type : v .Type (), Offset : int64 (d .off )})
461485 d .off --
462486 d .next ()
463487 return
@@ -476,7 +500,7 @@ func (d *decodeState) array(v reflect.Value) {
476500 // Otherwise it's invalid.
477501 fallthrough
478502 default :
479- d .saveError (& UnmarshalTypeError {"array" , v .Type (), int64 (d .off )})
503+ d .saveError (& UnmarshalTypeError {Value : "array" , Type : v .Type (), Offset : int64 (d .off )})
480504 d .off --
481505 d .next ()
482506 return
@@ -566,7 +590,7 @@ func (d *decodeState) object(v reflect.Value) {
566590 return
567591 }
568592 if ut != nil {
569- d .saveError (& UnmarshalTypeError {"object" , v .Type (), int64 (d .off )})
593+ d .saveError (& UnmarshalTypeError {Value : "object" , Type : v .Type (), Offset : int64 (d .off )})
570594 d .off --
571595 d .next () // skip over { } in input
572596 return
@@ -594,7 +618,7 @@ func (d *decodeState) object(v reflect.Value) {
594618 reflect .Uint , reflect .Uint8 , reflect .Uint16 , reflect .Uint32 , reflect .Uint64 , reflect .Uintptr :
595619 default :
596620 if ! reflect .PtrTo (t .Key ()).Implements (textUnmarshalerType ) {
597- d .saveError (& UnmarshalTypeError {"object" , v .Type (), int64 (d .off )})
621+ d .saveError (& UnmarshalTypeError {Value : "object" , Type : v .Type (), Offset : int64 (d .off )})
598622 d .off --
599623 d .next () // skip over { } in input
600624 return
@@ -604,9 +628,9 @@ func (d *decodeState) object(v reflect.Value) {
604628 v .Set (reflect .MakeMap (t ))
605629 }
606630 case reflect .Struct :
607-
631+ // ok
608632 default :
609- d .saveError (& UnmarshalTypeError {"object" , v .Type (), int64 (d .off )})
633+ d .saveError (& UnmarshalTypeError {Value : "object" , Type : v .Type (), Offset : int64 (d .off )})
610634 d .off --
611635 d .next () // skip over { } in input
612636 return
@@ -671,6 +695,8 @@ func (d *decodeState) object(v reflect.Value) {
671695 }
672696 subv = subv .Field (i )
673697 }
698+ d .errorContext .Field = f .name
699+ d .errorContext .Struct = v .Type ().Name ()
674700 }
675701 }
676702
@@ -682,7 +708,6 @@ func (d *decodeState) object(v reflect.Value) {
682708 d .error (errPhase )
683709 }
684710
685- // Read value.
686711 if destring {
687712 switch qv := d .valueQuoted ().(type ) {
688713 case nil :
@@ -714,15 +739,15 @@ func (d *decodeState) object(v reflect.Value) {
714739 s := string (key )
715740 n , err := strconv .ParseInt (s , 10 , 64 )
716741 if err != nil || reflect .Zero (kt ).OverflowInt (n ) {
717- d .saveError (& UnmarshalTypeError {"number " + s , kt , int64 (start + 1 )})
742+ d .saveError (& UnmarshalTypeError {Value : "number " + s , Type : kt , Offset : int64 (start + 1 )})
718743 return
719744 }
720745 kv = reflect .ValueOf (n ).Convert (kt )
721746 case reflect .Uint , reflect .Uint8 , reflect .Uint16 , reflect .Uint32 , reflect .Uint64 , reflect .Uintptr :
722747 s := string (key )
723748 n , err := strconv .ParseUint (s , 10 , 64 )
724749 if err != nil || reflect .Zero (kt ).OverflowUint (n ) {
725- d .saveError (& UnmarshalTypeError {"number " + s , kt , int64 (start + 1 )})
750+ d .saveError (& UnmarshalTypeError {Value : "number " + s , Type : kt , Offset : int64 (start + 1 )})
726751 return
727752 }
728753 kv = reflect .ValueOf (n ).Convert (kt )
@@ -741,6 +766,9 @@ func (d *decodeState) object(v reflect.Value) {
741766 if op != scanObjectValue {
742767 d .error (errPhase )
743768 }
769+
770+ d .errorContext .Struct = ""
771+ d .errorContext .Field = ""
744772 }
745773}
746774
@@ -767,7 +795,7 @@ func (d *decodeState) convertNumber(s string) (interface{}, error) {
767795 }
768796 f , err := strconv .ParseFloat (s , 64 )
769797 if err != nil {
770- return nil , & UnmarshalTypeError {"number " + s , reflect .TypeOf (0.0 ), int64 (d .off )}
798+ return nil , & UnmarshalTypeError {Value : "number " + s , Type : reflect .TypeOf (0.0 ), Offset : int64 (d .off )}
771799 }
772800 return f , nil
773801}
@@ -800,7 +828,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool
800828 if fromQuoted {
801829 d .saveError (fmt .Errorf ("json: invalid use of ,string struct tag, trying to unmarshal %q into %v" , item , v .Type ()))
802830 } else {
803- d .saveError (& UnmarshalTypeError {"string" , v .Type (), int64 (d .off )})
831+ d .saveError (& UnmarshalTypeError {Value : "string" , Type : v .Type (), Offset : int64 (d .off )})
804832 }
805833 return
806834 }
@@ -835,15 +863,15 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool
835863 if fromQuoted {
836864 d .saveError (fmt .Errorf ("json: invalid use of ,string struct tag, trying to unmarshal %q into %v" , item , v .Type ()))
837865 } else {
838- d .saveError (& UnmarshalTypeError {"bool" , v .Type (), int64 (d .off )})
866+ d .saveError (& UnmarshalTypeError {Value : "bool" , Type : v .Type (), Offset : int64 (d .off )})
839867 }
840868 case reflect .Bool :
841869 v .SetBool (value )
842870 case reflect .Interface :
843871 if v .NumMethod () == 0 {
844872 v .Set (reflect .ValueOf (value ))
845873 } else {
846- d .saveError (& UnmarshalTypeError {"bool" , v .Type (), int64 (d .off )})
874+ d .saveError (& UnmarshalTypeError {Value : "bool" , Type : v .Type (), Offset : int64 (d .off )})
847875 }
848876 }
849877
@@ -858,10 +886,10 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool
858886 }
859887 switch v .Kind () {
860888 default :
861- d .saveError (& UnmarshalTypeError {"string" , v .Type (), int64 (d .off )})
889+ d .saveError (& UnmarshalTypeError {Value : "string" , Type : v .Type (), Offset : int64 (d .off )})
862890 case reflect .Slice :
863891 if v .Type ().Elem ().Kind () != reflect .Uint8 {
864- d .saveError (& UnmarshalTypeError {"string" , v .Type (), int64 (d .off )})
892+ d .saveError (& UnmarshalTypeError {Value : "string" , Type : v .Type (), Offset : int64 (d .off )})
865893 break
866894 }
867895 b := make ([]byte , base64 .StdEncoding .DecodedLen (len (s )))
@@ -877,7 +905,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool
877905 if v .NumMethod () == 0 {
878906 v .Set (reflect .ValueOf (string (s )))
879907 } else {
880- d .saveError (& UnmarshalTypeError {"string" , v .Type (), int64 (d .off )})
908+ d .saveError (& UnmarshalTypeError {Value : "string" , Type : v .Type (), Offset : int64 (d .off )})
881909 }
882910 }
883911
@@ -902,7 +930,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool
902930 if fromQuoted {
903931 d .error (fmt .Errorf ("json: invalid use of ,string struct tag, trying to unmarshal %q into %v" , item , v .Type ()))
904932 } else {
905- d .error (& UnmarshalTypeError {"number" , v .Type (), int64 (d .off )})
933+ d .error (& UnmarshalTypeError {Value : "number" , Type : v .Type (), Offset : int64 (d .off )})
906934 }
907935 case reflect .Interface :
908936 n , err := d .convertNumber (s )
@@ -911,31 +939,31 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool
911939 break
912940 }
913941 if v .NumMethod () != 0 {
914- d .saveError (& UnmarshalTypeError {"number" , v .Type (), int64 (d .off )})
942+ d .saveError (& UnmarshalTypeError {Value : "number" , Type : v .Type (), Offset : int64 (d .off )})
915943 break
916944 }
917945 v .Set (reflect .ValueOf (n ))
918946
919947 case reflect .Int , reflect .Int8 , reflect .Int16 , reflect .Int32 , reflect .Int64 :
920948 n , err := strconv .ParseInt (s , 10 , 64 )
921949 if err != nil || v .OverflowInt (n ) {
922- d .saveError (& UnmarshalTypeError {"number " + s , v .Type (), int64 (d .off )})
950+ d .saveError (& UnmarshalTypeError {Value : "number " + s , Type : v .Type (), Offset : int64 (d .off )})
923951 break
924952 }
925953 v .SetInt (n )
926954
927955 case reflect .Uint , reflect .Uint8 , reflect .Uint16 , reflect .Uint32 , reflect .Uint64 , reflect .Uintptr :
928956 n , err := strconv .ParseUint (s , 10 , 64 )
929957 if err != nil || v .OverflowUint (n ) {
930- d .saveError (& UnmarshalTypeError {"number " + s , v .Type (), int64 (d .off )})
958+ d .saveError (& UnmarshalTypeError {Value : "number " + s , Type : v .Type (), Offset : int64 (d .off )})
931959 break
932960 }
933961 v .SetUint (n )
934962
935963 case reflect .Float32 , reflect .Float64 :
936964 n , err := strconv .ParseFloat (s , v .Type ().Bits ())
937965 if err != nil || v .OverflowFloat (n ) {
938- d .saveError (& UnmarshalTypeError {"number " + s , v .Type (), int64 (d .off )})
966+ d .saveError (& UnmarshalTypeError {Value : "number " + s , Type : v .Type (), Offset : int64 (d .off )})
939967 break
940968 }
941969 v .SetFloat (n )
0 commit comments