-
Notifications
You must be signed in to change notification settings - Fork 0
/
errs.go
158 lines (139 loc) · 2.83 KB
/
errs.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package errs
import (
"bytes"
"errors"
"io"
"io/fs"
"log"
"net"
"net/http"
"reflect"
"runtime/debug"
)
var Debug = true
func Panic(err error) {
if err != nil {
log.Panic(err)
}
}
func PrintWithDepthToLog(err error, depth int) bool {
if err == nil {
return false
}
return printWithDepth(err, depth+1, log.Writer(), log.Output)
}
func PrintWithDepthToLogger(err error, depth int, log *log.Logger) bool {
if err == nil {
return false
}
return printWithDepth(err, depth+1, log.Writer(), log.Output)
}
func PrintWithDepthToLogBuffer(err error, depth int) *bytes.Buffer {
if err == nil {
return nil
}
buf := &bytes.Buffer{}
PrintWithDepthToLogger(err, depth+1, log.New(buf, log.Prefix(), log.Flags()))
return buf
}
func printWithDepth(err error, depth int, writer io.Writer, output func(int, string) error) bool {
if err == nil {
return false
}
s := err.Error()
depth += 2
e := output(depth, s)
if e != nil {
log.Println(e)
log.Println(s)
}
if //goland:noinspection GoBoolExpressions
!Debug {
return true
}
stack := debug.Stack()
stackLine := stack
i := bytes.IndexByte(stackLine, '\n') + 1
stackLine = stack[:i]
_, e = writer.Write(stackLine)
if e != nil {
log.Println(e)
log.Println(string(stackLine))
}
stackLine = stack[i:]
depth *= 2
for line := 0; line < depth; line++ {
i = bytes.IndexByte(stackLine, '\n') + 1
if i == 0 {
break
}
stackLine = stackLine[i:]
}
_, e = writer.Write(stackLine)
if e != nil {
log.Println(e)
log.Println(string(stackLine))
}
return true
}
func Print(err error) bool {
return PrintWithDepthToLog(err, 1)
}
func printErr(err error) bool {
return PrintWithDepthToLog(err, 2)
}
func Close(closer io.Closer) {
printErr(closer.Close())
}
func CloseResponse(resp *http.Response) {
printErr(resp.Body.Close())
}
func Defer(fn func() error) {
printErr(fn())
}
func deferCall(fn func([]reflect.Value) []reflect.Value, args ...interface{}) {
var values []reflect.Value
for _, arg := range args {
values = append(values, reflect.ValueOf(arg))
}
values = fn(values)
length := len(values)
if length == 0 {
return
}
value := values[length-1].Interface()
if value == nil {
return
}
err, ok := value.(error)
if !ok {
return
}
PrintWithDepthToLog(err, 2)
}
func DeferCall(fn interface{}, args ...interface{}) {
deferCall(reflect.ValueOf(fn).Call, args...)
}
func DeferCallSlice(fn interface{}, args ...interface{}) {
deferCall(reflect.ValueOf(fn).CallSlice, args...)
}
func IsClosed(err error) bool {
return errors.Is(err, fs.ErrClosed) || errors.Is(err, net.ErrClosed)
}
func CloseIgnoreClosed(closer io.Closer) {
err := closer.Close()
if IsClosed(err) {
return
}
printErr(err)
}
func DeferIgnoreClosed(fn func() error) {
err := fn()
if IsClosed(err) {
return
}
printErr(err)
}
func SetLogFlag() {
log.SetFlags(log.Flags() | log.Llongfile)
}