From 93b3035dbbcd21c1d0538142cba4e7f79631e7a2 Mon Sep 17 00:00:00 2001 From: Jonathan Amsterdam Date: Wed, 29 Mar 2023 09:57:33 -0400 Subject: [PATCH] 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 TryBot-Result: Gopher Robot Reviewed-by: Alan Donovan --- src/log/slog/json_handler.go | 3 ++- src/log/slog/json_handler_test.go | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/log/slog/json_handler.go b/src/log/slog/json_handler.go index 96545d58d6..ce249acfd3 100644 --- a/src/log/slog/json_handler.go +++ b/src/log/slog/json_handler.go @@ -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) diff --git a/src/log/slog/json_handler_test.go b/src/log/slog/json_handler_test.go index 0a38969f46..7c683f0d34 100644 --- a/src/log/slog/json_handler_test.go +++ b/src/log/slog/json_handler_test.go @@ -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) -- 2.48.1