diff --git a/client.go b/client.go index d7b6a3b..aff398c 100644 --- a/client.go +++ b/client.go @@ -1074,8 +1074,15 @@ func init() { // } // // If the error does not implement Cause, the original error will -// be returned. If the error is nil, nil will be returned without further +// be returned. +// +// If the cause of the error is nil, then the original +// error will be returned. +// +// If the error is nil, nil will be returned without further // investigation. +// +// Will return the deepest cause which is not nil. func Cause(err error) error { type causer interface { Cause() error @@ -1086,7 +1093,13 @@ func Cause(err error) error { if !ok { break } - err = cause.Cause() + + if _cause := cause.Cause(); _cause != nil { + err = _cause + } else { + break + } + } return err } diff --git a/client_test.go b/client_test.go index 9ff8b4e..e766502 100644 --- a/client_test.go +++ b/client_test.go @@ -3,6 +3,7 @@ package raven import ( "encoding/json" "fmt" + pkgErrors "github.com/pkg/errors" "reflect" "testing" "time" @@ -286,6 +287,41 @@ func TestCaptureNilError(t *testing.T) { } } +// Custom error which implements causer +type customErr struct { + msg string + cause error +} + +func (e *customErr) Error() (errorMsg string) { + if e.msg != "" && e.cause != nil { + errorMsg = fmt.Sprintf("%v \n\t==>> %v", e.msg, e.cause) + } else if e.msg == "" && e.cause != nil { + errorMsg = fmt.Sprintf("%v", e.cause) + } else if e.msg != "" && e.cause == nil { + errorMsg = fmt.Sprintf("%s", e.msg) + } + return +} + +// Implementing the causer interface from github.com/pkg/errors +func (e *customErr) Cause() error { + return e.cause +} + +func TestCaptureNilCauseError(t *testing.T) { + var client = DefaultClient + err := pkgErrors.WithStack(&customErr{ + // Setting a nil cause + cause: nil, + msg: "This is a test", + }) + eventID := client.CaptureError(err, nil) + if eventID == "" { + t.Error("expected non-empty eventID:", eventID) + } +} + func TestNewPacketWithExtraSetsDefault(t *testing.T) { testCases := []struct { Extra Extra