I have a program with lots of goroutines, and I want to handle the panic globally. It looks like I have to add a recovery in each of the goroutines, is there a way to do it globally?
I wrote a test program and I add a recover() in main, but it won't catch the crash in other goroutines:
package main
import "log"
func bug2() {
panic("bug2()")
}
func bug1() {
go bug2()
}
func main() {
defer func() {
if r := recover(); r != nil {
log.Println("catched")
}
}()
bug1()
select {}
}
What's the best practice here?
CodePudding user response:
golang not support global recover()
. Recover() can only be executed in the current function or current goroutine.
package main
import (
"log"
"sync"
)
var wg sync.WaitGroup
func bug2() {
defer func() {
if r := recover(); r != nil {
log.Println("bug2 catched")
}
wg.Done()
}()
panic("bug2()")
}
func bug1() {
go bug2()
}
func main() {
wg.Add(1)
bug1()
wg.Wait()
}
result:
➜ src git:(master) ✗ go run recover_global_example.go
2022/09/13 11:33:33 bug2 catched
Or:
package main
import (
"log"
"sync"
)
func bug2() {
panic("bug2()")
}
func bug1() {
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer func() {
if r := recover(); r != nil {
log.Println("bug1 catched")
}
wg.Done()
}()
bug2()
}()
wg.Wait()
}
func main() {
bug1()
}
retult:
➜ src git:(master) ✗ go run recover_global_example3.go
2022/09/13 11:44:21 bug1 catched
CodePudding user response:
is there a way to do it globally?
No, not from inside code.
If you really need that (instead of fixing bugs that panic): Start your Go program via some monitor which restarts it in case of failure.