-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils_panic.go
More file actions
88 lines (77 loc) · 1.64 KB
/
utils_panic.go
File metadata and controls
88 lines (77 loc) · 1.64 KB
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
package box
import (
"github.com/suboat/go-contrib"
"github.com/suboat/go-contrib/log"
"fmt"
"runtime"
"strings"
)
var (
// LogPanic 输出panic错误
LogPanic Logger
)
// PanicRecover 统一处理panic
func PanicRecover(logger Logger) {
r := recover()
if r == nil {
return
}
if logger == nil && LogPanic != nil {
logger = LogPanic
} else {
logger = log.Log
}
logger.Errorf(`[panic-recover] "%s" %v`, panicIdentify(), r)
}
// PanicRecoverError 统一处理panic, 并更新error
func PanicRecoverError(logger Logger, err *error) {
r := recover()
if r == nil {
return
}
if logger == nil && LogPanic != nil {
logger = LogPanic
} else {
logger = log.Log
}
logger.Errorf(`[panic-recover] "%s" %v`, panicIdentify(), r)
if err != nil {
*err = contrib.ErrPanicRecover.SetVars(r)
}
return
}
// 定位panic位置 参考自: https://gist.github.com/swdunlop/9629168
func panicIdentify() string {
var (
pc [16]uintptr
n = runtime.Callers(3, pc[:])
)
for _, pc := range pc[:n] {
fn := runtime.FuncForPC(pc)
if fn == nil {
continue
}
_fnName := fn.Name()
if strings.HasPrefix(_fnName, "runtime.") {
continue
}
file, line := fn.FileLine(pc)
//
var (
_fnNameDir = strings.Split(_fnName, "/")
_fnNameLis = strings.Split(_fnName, ".")
_fnNameSrc string
)
if len(_fnNameDir) > 1 {
_fnNameSrc = _fnNameDir[0] + "/" + _fnNameDir[1] + "/"
} else {
_fnNameSrc = _fnNameDir[0]
}
fnName := _fnNameLis[len(_fnNameLis)-1]
// file
_pcLis := strings.Split(file, _fnNameSrc)
filePath := strings.Join(_pcLis[1:], "")
return fmt.Sprintf("%s:%d|%s", filePath, line, fnName)
}
return "unknown"
}