Skip to content

Commit

Permalink
BUGFIX: judge nil pointer stored in error interface
Browse files Browse the repository at this point in the history
  • Loading branch information
FMLS committed Nov 4, 2020
1 parent 404189c commit d63f5ec
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 6 deletions.
3 changes: 1 addition & 2 deletions error.go
Expand Up @@ -21,9 +21,8 @@
package zap

import (
"sync"

"go.uber.org/zap/zapcore"
"sync"
)

var _errArrayElemPool = sync.Pool{New: func() interface{} {
Expand Down
23 changes: 20 additions & 3 deletions zapcore/error.go
Expand Up @@ -22,6 +22,7 @@ package zapcore

import (
"fmt"
"reflect"
"sync"
)

Expand All @@ -42,13 +43,29 @@ import (
// ...
// ],
// }
func encodeError(key string, err error, enc ObjectEncoder) error {
func encodeError(key string, err error, enc ObjectEncoder) (retErr error) {
// Try to capture panics (from nil references or otherwise) when calling
// the Error() method
defer func() {
if err := recover(); err != nil {
// If it's a nil pointer, just say "<nil>". The likeliest causes are a
// Stringer that fails to guard against nil or a nil pointer for a
// value receiver, and in either case, "<nil>" is a nice result.
if v := reflect.ValueOf(err); v.Kind() == reflect.Ptr && v.IsNil() {
enc.AddString(key, "<nil>")
return
}

retErr = fmt.Errorf("PANIC=%v", err)
}
}()

basic := err.Error()
enc.AddString(key, basic)

switch e := err.(type) {
case errorGroup:
return enc.AddArray(key+"Causes", errArray(e.Errors()))
retErr = enc.AddArray(key+"Causes", errArray(e.Errors()))
case fmt.Formatter:
verbose := fmt.Sprintf("%+v", e)
if verbose != basic {
Expand All @@ -57,7 +74,7 @@ func encodeError(key string, err error, enc ObjectEncoder) error {
enc.AddString(key+"Verbose", verbose)
}
}
return nil
return retErr
}

type errorGroup interface {
Expand Down
2 changes: 1 addition & 1 deletion zapcore/field.go
Expand Up @@ -167,7 +167,7 @@ func (f Field) AddTo(enc ObjectEncoder) {
case StringerType:
err = encodeStringer(f.Key, f.Interface, enc)
case ErrorType:
encodeError(f.Key, f.Interface.(error), enc)
err = encodeError(f.Key, f.Interface.(error), enc)
case SkipType:
break
default:
Expand Down

0 comments on commit d63f5ec

Please sign in to comment.