(errToLog error)
| 52 | } |
| 53 | |
| 54 | func newSentryException(errToLog error) []sentry.Exception { |
| 55 | errMsg := errToLog.Error() |
| 56 | binPkg := "" |
| 57 | modPath := "" |
| 58 | if build, ok := debug.ReadBuildInfo(); ok { |
| 59 | binPkg = build.Path |
| 60 | modPath = build.Main.Path |
| 61 | } |
| 62 | |
| 63 | // Unwrap in a loop to get the most recent stack trace. stFunc is set to a |
| 64 | // function that can generate a stack trace for the most recent error. This |
| 65 | // avoids computing the full stack trace for every error. |
| 66 | var stFunc func() []runtime.Frame |
| 67 | errType := "Generic Error" |
| 68 | for { |
| 69 | if t := exportedErrType(errToLog); t != "" { |
| 70 | errType = t |
| 71 | } |
| 72 | |
| 73 | //nolint:errorlint |
| 74 | switch stackErr := errToLog.(type) { |
| 75 | // If the error implements the StackTrace method in the redact package, then |
| 76 | // prefer that. The Sentry SDK gets some things wrong when guessing how |
| 77 | // to extract the stack trace. |
| 78 | case interface{ StackTrace() []runtime.Frame }: |
| 79 | stFunc = stackErr.StackTrace |
| 80 | // Otherwise use the pkg/errors StackTracer interface. |
| 81 | case interface{ StackTrace() errors.StackTrace }: |
| 82 | // Normalize the pkgs/errors.StackTrace type to a slice of runtime.Frame. |
| 83 | stFunc = func() []runtime.Frame { |
| 84 | pkgStack := stackErr.StackTrace() |
| 85 | pc := make([]uintptr, len(pkgStack)) |
| 86 | for i := range pkgStack { |
| 87 | pc[i] = uintptr(pkgStack[i]) |
| 88 | } |
| 89 | frameIter := runtime.CallersFrames(pc) |
| 90 | frames := make([]runtime.Frame, 0, len(pc)) |
| 91 | for { |
| 92 | frame, more := frameIter.Next() |
| 93 | frames = append(frames, frame) |
| 94 | if !more { |
| 95 | break |
| 96 | } |
| 97 | } |
| 98 | return frames |
| 99 | } |
| 100 | } |
| 101 | uw := errors.Unwrap(errToLog) |
| 102 | if uw == nil { |
| 103 | break |
| 104 | } |
| 105 | errToLog = uw |
| 106 | } |
| 107 | ex := []sentry.Exception{{Type: errType, Value: errMsg}} |
| 108 | if stFunc != nil { |
| 109 | ex[0].Stacktrace = newSentryStack(stFunc(), binPkg, modPath) |
| 110 | } |
| 111 | return ex |
no test coverage detected