I used to think the panic in a goroutine will kill the program if its caller finishes before the panic (the deferred recovering gives no help since at that point there's no panic occurs yet),
until I tried following code:
func fun1() {
fmt.Println("fun1 started")
defer func() {
if err := recover(); err != nil {
fmt.Println("recover in func1")
}
}()
go fun2()
time.Sleep(10 * time.Second) // wait for the boom!
fmt.Println("fun1 ended")
}
func fun2() {
fmt.Println("fun2 started")
time.Sleep(5 * time.Second)
panic("fun2 booom!")
fmt.Println("fun2 ended")
}
I found no matter the caller function finishes or not, if the goroutines it starts panic, the caller's deferred recover mechanism will not help. The whole program is still dead.
So, WHY? Theoretically the caller function is still running. When the panics happen the caller's deferred functions should work (including the recovering).
Instead of recovering in fun1() you can use runtime.Goexit() in fun2() which will
Something like
The specification says:
Because
fun2
is the top-level function executing in the goroutine andfun2
does not recover from a panic, the program terminates whenfun2
panics.The deferred call in
fun1
is not called when the goroutine executingfun2
panics.A goroutine cannot recover from a panic in another goroutine.