Is it possible to "rethrow" an error from recover
and keep the original stack trace? The best I know how to do is to panic again, but that does create a new stacktrace.
func do() {
defer func() {
cleanUp()
if x := recover(); x != nil {
handleError()
panic(x)
}
}()
doStuff()
}
My motivation for wanting this is that unless my function exits normally or handleError
runs, my program deadlocks. And unless I preserve the original strack trace, I do not know where it crashed.
The solution is to not call recover
, because then neither rethrowing nor accessing the stack trace is possible. Use a bool flag instead of recover
to check for panic.
https://play.golang.org/p/PKeP9s-3tF
func do() {
panicked := true
defer func() {
cleanUp()
if panicked {
handleError()
}
}()
doStuff()
panicked = false
}
Defered functions higher up in the stack will run on panic, even if they don't call recover()
.
Simply remove the if-statement and the re-panic. Then handle your error, and let the panic continue up the stack.
func do() {
defer handleError()
doStuff()
}
a simple demo:
https://play.golang.org/p/UiRou5MhUR
func a() {
defer func() {
fmt.Println("a")
}()
panic("test")
}
func b() {
defer func() {
fmt.Println("b")
}()
}
func main() {
fmt.Println("Hello, playground")
b()
}
outputs
Hello, playground
b