Skip to content

Commit 02196d3

Browse files
ekalininianlancetaylor
authored andcommitted
encoding/json: correct caller's name in encoding errors
1. Change mapencode.encode to use fmt.Error rather than MarshalerError. MarshalerError refer to MarshalJSON, but mapencode.encode does not use that. 2. Add sourceFunc field to MarshalerError to record the name of the function that creates the error, so that the Error method can report it correctly. Fixes #29753 Change-Id: I186c2fac8470ae2f9e300501de3730face642230 Reviewed-on: https://go-review.googlesource.com/c/go/+/184119 Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 943df4f commit 02196d3

File tree

2 files changed

+43
-8
lines changed

2 files changed

+43
-8
lines changed

src/encoding/json/encode.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -261,14 +261,22 @@ func (e *InvalidUTF8Error) Error() string {
261261

262262
// A MarshalerError represents an error from calling a MarshalJSON or MarshalText method.
263263
type MarshalerError struct {
264-
Type reflect.Type
265-
Err error
264+
Type reflect.Type
265+
Err error
266+
sourceFunc string
266267
}
267268

268269
func (e *MarshalerError) Error() string {
269-
return "json: error calling MarshalJSON for type " + e.Type.String() + ": " + e.Err.Error()
270+
srcFunc := e.sourceFunc
271+
if srcFunc == "" {
272+
srcFunc = "MarshalJSON"
273+
}
274+
return "json: error calling " + srcFunc +
275+
" for type " + e.Type.String() +
276+
": " + e.Err.Error()
270277
}
271278

279+
// Unwrap returns the underlying error.
272280
func (e *MarshalerError) Unwrap() error { return e.Err }
273281

274282
var hex = "0123456789abcdef"
@@ -455,7 +463,7 @@ func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
455463
err = compact(&e.Buffer, b, opts.escapeHTML)
456464
}
457465
if err != nil {
458-
e.error(&MarshalerError{v.Type(), err})
466+
e.error(&MarshalerError{v.Type(), err, "MarshalJSON"})
459467
}
460468
}
461469

@@ -472,7 +480,7 @@ func addrMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
472480
err = compact(&e.Buffer, b, opts.escapeHTML)
473481
}
474482
if err != nil {
475-
e.error(&MarshalerError{v.Type(), err})
483+
e.error(&MarshalerError{v.Type(), err, "MarshalJSON"})
476484
}
477485
}
478486

@@ -488,7 +496,7 @@ func textMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
488496
}
489497
b, err := m.MarshalText()
490498
if err != nil {
491-
e.error(&MarshalerError{v.Type(), err})
499+
e.error(&MarshalerError{v.Type(), err, "MarshalText"})
492500
}
493501
e.stringBytes(b, opts.escapeHTML)
494502
}
@@ -502,7 +510,7 @@ func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
502510
m := va.Interface().(encoding.TextMarshaler)
503511
b, err := m.MarshalText()
504512
if err != nil {
505-
e.error(&MarshalerError{v.Type(), err})
513+
e.error(&MarshalerError{v.Type(), err, "MarshalText"})
506514
}
507515
e.stringBytes(b, opts.escapeHTML)
508516
}
@@ -761,7 +769,7 @@ func (me mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
761769
for i, v := range keys {
762770
sv[i].v = v
763771
if err := sv[i].resolve(); err != nil {
764-
e.error(&MarshalerError{v.Type(), err})
772+
e.error(fmt.Errorf("json: encoding error for type %q: %q", v.Type().String(), err.Error()))
765773
}
766774
}
767775
sort.Slice(sv, func(i, j int) bool { return sv[i].s < sv[j].s })

src/encoding/json/encode_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,3 +1064,30 @@ func TestMarshalUncommonFieldNames(t *testing.T) {
10641064
t.Fatalf("Marshal: got %s want %s", got, want)
10651065
}
10661066
}
1067+
1068+
func TestMarshalerError(t *testing.T) {
1069+
s := "test variable"
1070+
st := reflect.TypeOf(s)
1071+
errText := "json: test error"
1072+
1073+
tests := []struct {
1074+
err *MarshalerError
1075+
want string
1076+
}{
1077+
{
1078+
&MarshalerError{st, fmt.Errorf(errText), ""},
1079+
"json: error calling MarshalJSON for type " + st.String() + ": " + errText,
1080+
},
1081+
{
1082+
&MarshalerError{st, fmt.Errorf(errText), "TestMarshalerError"},
1083+
"json: error calling TestMarshalerError for type " + st.String() + ": " + errText,
1084+
},
1085+
}
1086+
1087+
for i, tt := range tests {
1088+
got := tt.err.Error()
1089+
if got != tt.want {
1090+
t.Errorf("MarshalerError test %d, got: %s, want: %s", i, got, tt.want)
1091+
}
1092+
}
1093+
}

0 commit comments

Comments
 (0)