Skip to content

Commit 66acaa3

Browse files
authored
Update Stringer panic check to look like stdlib (uber-go#857)
There's no behaviour changes, but there are a couple of refactorings: * Name the named return error `retErr`, and use explicit return values. The only purpose of the named return is for the panic handling. * Make the panic handling look more similar to the standard library and add a reference to the stdlib code in fmt that does the same checks.
1 parent 8c4fdeb commit 66acaa3

File tree

1 file changed

+12
-7
lines changed

1 file changed

+12
-7
lines changed

zapcore/field.go

+12-7
Original file line numberDiff line numberDiff line change
@@ -205,18 +205,23 @@ func addFields(enc ObjectEncoder, fields []Field) {
205205
}
206206
}
207207

208-
func encodeStringer(key string, stringer interface{}, enc ObjectEncoder) (err error) {
208+
func encodeStringer(key string, stringer interface{}, enc ObjectEncoder) (retErr error) {
209+
// Try to capture panics (from nil references or otherwise) when calling
210+
// the String() method, similar to https://golang.org/src/fmt/print.go#L540
209211
defer func() {
210-
if v := recover(); v != nil {
211-
val := reflect.ValueOf(stringer)
212-
if val.Kind() == reflect.Ptr && val.IsNil() {
212+
if err := recover(); err != nil {
213+
// If it's a nil pointer, just say "<nil>". The likeliest causes are a
214+
// Stringer that fails to guard against nil or a nil pointer for a
215+
// value receiver, and in either case, "<nil>" is a nice result.
216+
if v := reflect.ValueOf(stringer); v.Kind() == reflect.Ptr && v.IsNil() {
213217
enc.AddString(key, "<nil>")
214-
} else {
215-
err = fmt.Errorf("PANIC=%v", v)
218+
return
216219
}
220+
221+
retErr = fmt.Errorf("PANIC=%v", err)
217222
}
218223
}()
219224

220225
enc.AddString(key, stringer.(fmt.Stringer).String())
221-
return
226+
return nil
222227
}

0 commit comments

Comments
 (0)