-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhandle.go
More file actions
46 lines (41 loc) · 1.15 KB
/
Copy pathhandle.go
File metadata and controls
46 lines (41 loc) · 1.15 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
// Handle panics in a simple manner.
package panichandler
import (
"fmt"
"os"
"runtime/debug"
)
// ExitCode used if one isn't provided.
// This can be set with panichandler.ExitCode = code.
var ExitCode = 111
func caller(i *Info, c HandlerFunc, e int) bool {
if c == nil {
return false
}
defer nestedPanic(i, e)
c(i)
return true
}
// Catch a panic within the function designed to run upon receiving a panic.
// This will crash the program after printing out all stack traces.
func nestedPanic(i *Info, e int) {
iN := newInfo(recover(), debug.Stack())
if iN == nil {
return
}
fmt.Fprintf(os.Stderr, "WARNING!!!\nA panic within a panic catching function has been detected, this is a severe bug. Never fear, all stack traces are below.\nOriginally caught panic:\n%s\nPanic caused while catching original panic:\n%s\n", i.String(), iN.String())
os.Exit(e)
}
// Handle panics. Call this in a defer statement, like this.
// panichandler.Handle(panichandler.HandlerFunc).
func Handle(c HandlerFunc) {
i := newInfo(recover(), debug.Stack())
if i == nil {
return
}
if caller(i, c, ExitCode) {
return
}
fmt.Fprintln(os.Stderr, i.String())
os.Exit(ExitCode)
}