-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patherrors.go
116 lines (99 loc) · 2.86 KB
/
errors.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
package bugsnag
import (
"fmt"
"os"
"path/filepath"
"reflect"
"runtime"
"strings"
)
type stacktraceFrame struct {
File string `json:"file"`
LineNumber uint `json:"lineNumber"`
Method string `json:"method"`
}
type bugsnagException struct {
ErrorClass string `json:"errorClass"`
Message string `json:"message"`
StackTrace []stacktraceFrame `json:"stacktrace"`
}
type bugsnagEvent struct {
UserId string `json:"userId,omitempty"`
AppVersion string `json:"appVersion,omitempty"`
OsVersion string `json:"osVersion,omitempty"`
ReleaseStage string `json:"releaseStage"`
Context string `json:"context,omitempty"`
GroupingHash string `json:"groupingHash,omitempty"`
Exceptions []bugsnagException `json:"exceptions"`
}
type bugsnagNotification struct {
ApiKey string `json:"apiKey"`
NotifierInfo *notifierInfo `json:"notifier"`
Events []bugsnagEvent `json:"events"`
}
func getErrorTypeName(err interface{}) string {
errorType := reflect.TypeOf(err)
if errorType.Kind() == reflect.Ptr {
errorType = errorType.Elem()
}
return fmt.Sprintf("%s:%s", errorType.PkgPath(), errorType.Name())
}
func getStackFrames(skipFrames, maxFrames int) []stacktraceFrame {
if skipFrames < 0 {
skipFrames = 0
}
callers := make([]uintptr, maxFrames)
depth := runtime.Callers(skipFrames+2, callers)
output := make([]stacktraceFrame, depth)
written := 0
for i := 0; i < depth; i++ {
pc := callers[i]
fn := runtime.FuncForPC(pc)
if fn == nil {
break
} else if fn.Name() == "runtime.panic" {
continue
}
filename, line := fn.FileLine(pc)
filename = simplifyFilePath(filename)
output[written] = stacktraceFrame{File: filename, LineNumber: uint(line), Method: fn.Name()}
written++
}
return output[:written]
}
var goroot string
var sourcePaths []string
func init() {
goroot = filepath.Join(runtime.GOROOT(), "src", "pkg") + string(os.PathSeparator)
sourcePaths = strings.Split(os.Getenv("GOPATH"), ":")
}
func simplifyFilePath(path string) string {
pathLen := len(path)
if strings.HasPrefix(path, goroot) && pathLen > len(goroot) {
return path[len(goroot):]
}
for _, tmpPath := range sourcePaths {
var check string
if len(tmpPath) > 1 && os.IsPathSeparator(tmpPath[0]) {
check = tmpPath[1:]
} else {
check = tmpPath
}
if strings.HasPrefix(path, check) && pathLen > len(check) {
var src, pkg string
src = path + "src" + string(os.PathSeparator)
pkg = path + "pkg" + string(os.PathSeparator)
if strings.HasPrefix(path, src) && pathLen > len(src) {
return path[len(src):]
} else if strings.HasPrefix(path, pkg) && pathLen > len(pkg) {
return path[len(pkg):]
} else {
return path[len(check):]
}
}
}
if pathLen > 1 && os.IsPathSeparator(path[0]) {
path = path[1:]
}
return path
}