diff --git a/json_logger.go b/json_logger.go index 0cedbf8..d0faed4 100644 --- a/json_logger.go +++ b/json_logger.go @@ -68,7 +68,7 @@ func safeString(str fmt.Stringer) (s string) { if v := reflect.ValueOf(str); v.Kind() == reflect.Ptr && v.IsNil() { s = "NULL" } else { - panic(panicVal) + s = fmt.Sprintf("PANIC in String method: %v", panicVal) } } }() @@ -82,7 +82,7 @@ func safeError(err error) (s interface{}) { if v := reflect.ValueOf(err); v.Kind() == reflect.Ptr && v.IsNil() { s = nil } else { - panic(panicVal) + s = fmt.Sprintf("PANIC in Error method: %v", panicVal) } } }() diff --git a/json_logger_test.go b/json_logger_test.go index cb049dd..a7ef4ea 100644 --- a/json_logger_test.go +++ b/json_logger_test.go @@ -60,6 +60,19 @@ func TestJSONLoggerNilStringerKey(t *testing.T) { } } +func TestJSONLoggerPanicStringerValue(t *testing.T) { + t.Parallel() + + buf := &bytes.Buffer{} + logger := log.NewJSONLogger(buf) + if err := logger.Log("k", unsafeStringer{}); err != nil { + t.Fatal(err) + } + if want, have := `{"k":"PANIC in String method: error"}`+"\n", buf.String(); want != have { + t.Errorf("\nwant %#v\nhave %#v", want, have) + } +} + func TestJSONLoggerNilErrorValue(t *testing.T) { t.Parallel() @@ -73,6 +86,19 @@ func TestJSONLoggerNilErrorValue(t *testing.T) { } } +func TestJSONLoggerPanicErrorValue(t *testing.T) { + t.Parallel() + + buf := &bytes.Buffer{} + logger := log.NewJSONLogger(buf) + if err := logger.Log("err", unsafeError{}); err != nil { + t.Fatal(err) + } + if want, have := `{"err":"PANIC in Error method: error"}`+"\n", buf.String(); want != have { + t.Errorf("\nwant %#v\nhave %#v", want, have) + } +} + func TestJSONLoggerNoHTMLEscape(t *testing.T) { t.Parallel() buf := &bytes.Buffer{} @@ -160,6 +186,18 @@ func (s stringError) Error() string { return string(s) } +type unsafeStringer struct{} + +func (s unsafeStringer) String() string { + panic("error") +} + +type unsafeError struct{} + +func (s unsafeError) Error() string { + panic("error") +} + func BenchmarkJSONLoggerSimple(b *testing.B) { benchmarkRunner(b, log.NewJSONLogger(ioutil.Discard), baseMessage) }