1
0
mirror of https://github.com/golang/go synced 2024-09-29 04:14:27 -06:00

src/log/slog: JSONHandler checks if error implements json.Marshaler

json.Marshal doesn't do what one might hope on many Go error values.
Errors created with errors.New marshal as "{}". So JSONHandler treats
errors specially, calling the Error method instead of json.Marshal.

However, if the error happens to implement json.Marshaler, then
JSONHandler should call json.Marshal after all. This CL makes
that change.

Change-Id: I2154246b2ca8fa13d4f6f1256f7a16aa98a8c24a
Reviewed-on: https://go-review.googlesource.com/c/go/+/480155
Run-TryBot: Jonathan Amsterdam <jba@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
Jonathan Amsterdam 2023-03-29 09:57:33 -04:00
parent 1844b54166
commit 93b3035dbb
2 changed files with 9 additions and 1 deletions

View File

@ -135,7 +135,8 @@ func appendJSONValue(s *handleState, v Value) error {
s.appendTime(v.Time())
case KindAny:
a := v.Any()
if err, ok := a.(error); ok {
_, jm := a.(json.Marshaler)
if err, ok := a.(error); ok && !jm {
s.appendString(err.Error())
} else {
return appendJSONMarshal(s.buf, a)

View File

@ -67,6 +67,12 @@ func (j jsonMarshaler) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprintf(`[%q]`, j.s)), nil
}
type jsonMarshalerError struct {
jsonMarshaler
}
func (jsonMarshalerError) Error() string { return "oops" }
func TestAppendJSONValue(t *testing.T) {
// On most values, jsonAppendAttrValue should agree with json.Marshal.
for _, value := range []any{
@ -82,6 +88,7 @@ func TestAppendJSONValue(t *testing.T) {
time.Minute,
testTime,
jsonMarshaler{"xyz"},
jsonMarshalerError{jsonMarshaler{"pqr"}},
} {
got := jsonValueString(t, AnyValue(value))
want, err := marshalJSON(value)