-
Notifications
You must be signed in to change notification settings - Fork 0
/
sentry.go
138 lines (115 loc) · 3.03 KB
/
sentry.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package serrs
import (
"context"
"fmt"
sentry "github.com/getsentry/sentry-go"
)
// StackTrace is a method to get the stack trace of the error for sentry-go
// https://github.com/getsentry/sentry-go/blob/master/stacktrace.go#L84-L87
func (s *simpleError) StackTrace() []uintptr {
origin := originSimpleError(s)
if origin == nil {
return []uintptr{}
}
if len(origin.frames) <= 1 {
return origin.frames
}
return origin.frames[1:]
}
// GenerateSentryEvent is a method to generate a sentry event from an error
func GenerateSentryEvent(err error, ws ...sentryWrapper) *sentry.Event {
if err == nil {
return nil
}
exceptionType := Origin(err).Error()
errCode, ok := GetErrorCode(err)
if !ok {
errCode = DefaultCode("unknown")
} else {
exceptionType = fmt.Sprintf("[%s] %s", errCode, exceptionType)
}
event := sentry.NewEvent()
event.Level = sentry.LevelError
event.Exception = []sentry.Exception{{
Value: err.Error(),
Type: exceptionType,
Stacktrace: sentry.ExtractStacktrace(err),
}}
event.Contexts = map[string]sentry.Context{
"error detail": {
"history": StackedErrorJson(err),
"code": errCode.ErrorCode(),
},
}
for _, w := range ws {
w.wrap(event)
}
return event
}
// ReportSentry is a method to report an error to sentry
func ReportSentry(err error, ws ...sentryWrapper) {
event := GenerateSentryEvent(err, ws...)
sentry.CaptureEvent(event)
}
// ReportSentryWithContext is a method to report an error to sentry with a context
func ReportSentryWithContext(ctx context.Context, err error, ws ...sentryWrapper) {
hub := sentry.GetHubFromContext(ctx)
if hub == nil {
ReportSentry(err, ws...)
return
}
event := GenerateSentryEvent(err, ws...)
hub.CaptureEvent(event)
}
type sentryWrapper interface {
wrap(event *sentry.Event) *sentry.Event
}
// WithSentryContexts is a function to add contexts to a sentry event
func WithSentryContexts(m map[string]sentry.Context) sentryWrapper {
return sentryEventContextWrapper{m}
}
type sentryEventContextWrapper struct {
m map[string]sentry.Context
}
func (s sentryEventContextWrapper) wrap(event *sentry.Event) *sentry.Event {
for k, v := range s.m {
event.Contexts[k] = v
}
return event
}
// WithSentryTags is a function to add tags to a sentry event
func WithSentryTags(m map[string]string) sentryWrapper {
return sentryEventTagWrapper{m}
}
type sentryEventTagWrapper struct {
m map[string]string
}
func (s sentryEventTagWrapper) wrap(event *sentry.Event) *sentry.Event {
for k, v := range s.m {
event.Tags[k] = v
}
return event
}
// WithSentryLevel is a function to set the level of a sentry event
func WithSentryLevel(l sentry.Level) sentryWrapper {
return sentryEventLevelWrapper{l}
}
type sentryEventLevelWrapper struct {
l sentry.Level
}
func (s sentryEventLevelWrapper) wrap(event *sentry.Event) *sentry.Event {
event.Level = s.l
return event
}
func originSimpleError(err error) *simpleError {
var e *simpleError
for {
if err == nil {
return e
}
if ee := asSimpleError(err); ee != nil {
e = ee
}
err = Unwrap(err)
}
}