aboutsummaryrefslogtreecommitdiff
path: root/src/encoding/json
diff options
context:
space:
mode:
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)
+ }
+ }
+}