/
debug.go
111 lines (93 loc) · 2.07 KB
/
debug.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
package misc
import (
"encoding/json"
"fmt"
"path/filepath"
"runtime"
"runtime/debug"
"strings"
)
type Error struct {
Caller string `json:"caller,omitempty"`
Filepath string `json:"filepath,omitempty"`
Line int `json:"line,omitempty"`
Err error `json:"err,omitempty"`
}
func (err Error) Error() string {
return fmt.Sprintf("%s(%s:%d): %v", err.Caller, err.Filepath, err.Line, err.Err)
}
/*
func WrapError0(err error) error {
if err == nil {
return nil
}
pc := make([]uintptr, 20)
// fn, file, line, _ := runtime.Caller(1)
skip := runtime.Callers(2, pc)
fn, file, line, _ := runtime.Caller(skip - 2)
for i := range pc {
if pc[i] == 0 {
break
}
fmt.Println(" ", i, runtime.FuncForPC(pc[i]).Name())
}
return fmt.Errorf(
"%s(%s:%d): %w", runtime.FuncForPC(fn).Name(),
filepath.Base(file), line, err,
)
}
*/
func WrapError(err error, skips ...int) error {
if err == nil {
return nil
}
skip := 1
if len(skips) > 0 {
skip = skips[0]
}
fn, file, line, _ := runtime.Caller(skip)
/*
return fmt.Errorf(
"%s(%s:%d): %w", runtime.FuncForPC(fn).Name(),
filepath.Base(file), line, err,
)
*/
return Error{
Caller: runtime.FuncForPC(fn).Name(),
Filepath: filepath.Base(file),
Line: line,
Err: err,
}
}
func GetPanic(n int) {
var intf interface{}
if intf = recover(); intf == nil {
return
}
// fmt.Printf("%s\n", debug.Stack())
mp := map[string]string{
"kind": "panic",
"message": fmt.Sprintf("%v", intf),
"stack": SimplifyDebugStack(debug.Stack(), n),
}
bts, _ := json.MarshalIndent(mp, "", " ")
fmt.Printf("%s\n", bts)
}
func SimplifyDebugStack(bts []byte, n int) string {
strs := strings.Split(strings.TrimSpace(string(bts)), "\n")
builder := new(strings.Builder)
builder.WriteString(strs[0])
max := (len(strs) - 7) / 2
if n < 1 || n > max {
n = max
}
for i := 7; i < 2*n+7; i++ {
if i%2 == 1 {
builder.WriteString("\n" + strings.Split(strs[i], "(")[0])
} else {
t := filepath.Base(strings.Fields(strs[i])[0])
builder.WriteString("(" + t + ")")
}
}
return builder.String()
}