Home > database >  Does golang support global recovery?
Does golang support global recovery?

Time:09-13

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.

  • Related