I understand that to handle panic recover is used. But the following block fails to recover when panic arises in go routine
func main() {
done := make(chan int64)
defer fmt.Println("Graceful End of program")
defer func() {
r := recover()
if _, ok := r.(error); ok {
fmt.Println("Recovered")
}
}()
go handle(done)
for {
select{
case <- done:
return
}
}
}
func handle(done chan int64) {
var a *int64
a = nil
fmt.Println(*a)
done <- *a
}
However following block is able to execute as expected
func main() {
done := make(chan int64)
defer fmt.Println("Graceful End of program")
defer func() {
r := recover()
if _, ok := r.(error); ok {
fmt.Println("Recovered")
}
}()
handle(done)
for {
select{
case <- done:
return
}
}
}
func handle(done chan int64) {
var a *int64
a = nil
fmt.Println(*a)
done <- *a
}
How to recover from panics that arise in go routines. Here is the link for playground : https://play.golang.org/p/lkvKUxMHjhi
Recover only works when called from the same goroutine as the panic is called in. From the Go blog:
The process continues up the stack until all functions in the current goroutine have returned, at which point the program crashes
You would have to have a deferred recover within the goroutine.
https://blog.golang.org/defer-panic-and-recover
The docs / spec also includes the same :
While executing a function F, an explicit call to panic or a run-time panic terminates the execution of F. Any functions deferred by F are then executed as usual. Next, any deferred functions run by F's caller are run, and so on up to any deferred by the top-level function in the executing goroutine. At that point, the program is terminated and the error condition is reported, including the value of the argument to panic. This termination sequence is called panicking