diff --git a/client.go b/client.go index a2c9a6c..961526a 100644 --- a/client.go +++ b/client.go @@ -709,7 +709,7 @@ func (client *Client) CaptureError(err error, tags map[string]string, interfaces extra := extractExtra(err) cause := pkgErrors.Cause(err) - packet := NewPacketWithExtra(err.Error(), extra, append(append(interfaces, client.context.interfaces()...), NewException(cause, GetOrNewStacktrace(cause, 1, 3, client.includePaths)))...) + packet := NewPacketWithExtra(err.Error(), extra, append(append(interfaces, client.context.interfaces()...), NewException(cause, GetOrNewStacktrace(err, cause, 1, 3, client.includePaths)))...) eventID, _ := client.Capture(packet, tags) return eventID @@ -734,7 +734,7 @@ func (client *Client) CaptureErrorAndWait(err error, tags map[string]string, int extra := extractExtra(err) cause := pkgErrors.Cause(err) - packet := NewPacketWithExtra(err.Error(), extra, append(append(interfaces, client.context.interfaces()...), NewException(cause, GetOrNewStacktrace(cause, 1, 3, client.includePaths)))...) + packet := NewPacketWithExtra(err.Error(), extra, append(append(interfaces, client.context.interfaces()...), NewException(cause, GetOrNewStacktrace(err, cause, 1, 3, client.includePaths)))...) eventID, ch := client.Capture(packet, tags) if eventID != "" { <-ch diff --git a/stacktrace.go b/stacktrace.go index 4db79b4..eddd4aa 100644 --- a/stacktrace.go +++ b/stacktrace.go @@ -52,12 +52,24 @@ type StacktraceFrame struct { InApp bool `json:"in_app"` } +type StackTracer interface { + StackTrace() errors.StackTrace +} + // Try to get stacktrace from err as an interface of github.com/pkg/errors, or else NewStacktrace() -func GetOrNewStacktrace(err error, skip int, context int, appPackagePrefixes []string) *Stacktrace { - stacktracer, errHasStacktrace := err.(interface { - StackTrace() errors.StackTrace - }) - if errHasStacktrace { +func GetOrNewStacktrace(err, cause error, skip int, context int, appPackagePrefixes []string) *Stacktrace { + // use the stacktrace of cause + var stacktracer StackTracer + var causeHasStacktrace, errHasStacktrace bool + stacktracer, causeHasStacktrace = cause.(StackTracer) + + // if cause doesn't have a stacktrace, use the one of err + if !causeHasStacktrace { + stacktracer, errHasStacktrace = err.(StackTracer) + } + + // if either has a trace, we can generate from it + if causeHasStacktrace || errHasStacktrace { var frames []*StacktraceFrame for _, f := range stacktracer.StackTrace() { pc := uintptr(f) - 1