aboutsummaryrefslogtreecommitdiff
path: root/src/encoding/json
diff options
context:
space:
mode:
authorEugene Kalinin <e.v.kalinin@gmail.com>2019-06-28 23:59:49 +0300
committerIan Lance Taylor <iant@golang.org>2019-10-16 22:58:08 +0000
commit02196d36575636a64f868ee0ffe6bb61442e7245 (patch)
tree79a31755b7516b27eef4ec7e0c76bfead383633a /src/encoding/json
parent943df4f629560f5c33474dd82e2b534ea5f8653f (diff)
downloadgo-02196d36575636a64f868ee0ffe6bb61442e7245.tar.gz
go-02196d36575636a64f868ee0ffe6bb61442e7245.zip
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 <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/encoding/json')
-rw-r--r--src/encoding/json/encode.go24
-rw-r--r--src/encoding/json/encode_test.go27
2 files changed, 43 insertions, 8 deletions
diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go
index b4fba476c8..a7473a7eba 100644
--- a/src/encoding/json/encode.go
+++ b/src/encoding/json/encode.go
@@ -261,14 +261,22 @@ func (e *InvalidUTF8Error) Error() string {
// A MarshalerError represents an error from calling a MarshalJSON or MarshalText method.
type MarshalerError struct {
- Type reflect.Type
- Err error
+ Type reflect.Type
+ Err error
+ sourceFunc string
}
func (e *MarshalerError) Error() string {
- return "json: error calling MarshalJSON for type " + e.Type.String() + ": " + e.Err.Error()
+ srcFunc := e.sourceFunc
+ if srcFunc == "" {
+ srcFunc = "MarshalJSON"
+ }
+ return "json: error calling " + srcFunc +
+ " for type " + e.Type.String() +
+ ": " + e.Err.Error()
}
+// Unwrap returns the underlying error.
func (e *MarshalerError) Unwrap() error { return e.Err }
var hex = "0123456789abcdef"
@@ -455,7 +463,7 @@ func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
err = compact(&e.Buffer, b, opts.escapeHTML)
}
if err != nil {
- e.error(&MarshalerError{v.Type(), err})
+ e.error(&MarshalerError{v.Type(), err, "MarshalJSON"})
}
}
@@ -472,7 +480,7 @@ func addrMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
err = compact(&e.Buffer, b, opts.escapeHTML)
}
if err != nil {
- e.error(&MarshalerError{v.Type(), err})
+ e.error(&MarshalerError{v.Type(), err, "MarshalJSON"})
}
}
@@ -488,7 +496,7 @@ func textMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
}
b, err := m.MarshalText()
if err != nil {
- e.error(&MarshalerError{v.Type(), err})
+ e.error(&MarshalerError{v.Type(), err, "MarshalText"})
}
e.stringBytes(b, opts.escapeHTML)
}
@@ -502,7 +510,7 @@ func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
m := va.Interface().(encoding.TextMarshaler)
b, err := m.MarshalText()
if err != nil {
- e.error(&MarshalerError{v.Type(), err})
+ e.error(&MarshalerError{v.Type(), err, "MarshalText"})
}
e.stringBytes(b, opts.escapeHTML)
}
@@ -761,7 +769,7 @@ func (me mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
for i, v := range keys {
sv[i].v = v
if err := sv[i].resolve(); err != nil {
- e.error(&MarshalerError{v.Type(), err})
+ e.error(fmt.Errorf("json: encoding error for type %q: %q", v.Type().String(), err.Error()))
}
}
sort.Slice(sv, func(i, j int) bool { return sv[i].s < sv[j].s })
diff --git a/src/encoding/json/encode_test.go b/src/encoding/json/encode_test.go
index 8d3503b1ba..40f16d86ff 100644
--- a/src/encoding/json/encode_test.go
+++ b/src/encoding/json/encode_test.go
@@ -1064,3 +1064,30 @@ func TestMarshalUncommonFieldNames(t *testing.T) {
t.Fatalf("Marshal: got %s want %s", got, want)
}
}
+
+func TestMarshalerError(t *testing.T) {
+ s := "test variable"
+ st := reflect.TypeOf(s)
+ errText := "json: test error"
+
+ tests := []struct {
+ err *MarshalerError
+ want string
+ }{
+ {
+ &MarshalerError{st, fmt.Errorf(errText), ""},
+ "json: error calling MarshalJSON for type " + st.String() + ": " + errText,
+ },
+ {
+ &MarshalerError{st, fmt.Errorf(errText), "TestMarshalerError"},
+ "json: error calling TestMarshalerError for type " + st.String() + ": " + errText,
+ },
+ }
+
+ for i, tt := range tests {
+ got := tt.err.Error()
+ if got != tt.want {
+ t.Errorf("MarshalerError test %d, got: %s, want: %s", i, got, tt.want)
+ }
+ }
+}