Skip to content

Commit

Permalink
Intelligent errors.Cause()
Browse files Browse the repository at this point in the history
When causer.Cause() returns nil or itself, it is the cause.
  • Loading branch information
jaekwon authored Dec 21, 2017
1 parent e881fd5 commit c1d72bb
Showing 1 changed file with 10 additions and 7 deletions.
17 changes: 10 additions & 7 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@
// }
//
// can be inspected by errors.Cause. errors.Cause will recursively retrieve
// the topmost error which does not implement causer, which is assumed to be
// the original cause. For example:
// the topmost error which does not implement causer (which is assumed to be
// the original cause), or the error which returns nil or itself as the cause.
// For example:
//
// switch err := errors.Cause(err).(type) {
// case *MyError:
Expand Down Expand Up @@ -250,9 +251,8 @@ func (w *withMessage) Format(s fmt.State, verb rune) {
// Cause() error
// }
//
// If the error does not implement Cause, the original error will
// be returned. If the error is nil, nil will be returned without further
// investigation.
// An underlying cause is one which does not implement clause,
// or one which returns nil or itself as the cause.
func Cause(err error) error {
type causer interface {
Cause() error
Expand All @@ -261,9 +261,12 @@ func Cause(err error) error {
for err != nil {
cause, ok := err.(causer)
if !ok {
break
return err
}
errCause := cause.Cause()
if errCause == nil || errCause == err {
return err
}
err = cause.Cause()
}
return err
}

0 comments on commit c1d72bb

Please sign in to comment.