Go

Does the recover in main protect this program?

Question 503MediumGo 1.22 to 1.25
func main() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("recovered", r)
        }
    }()
    var wg sync.WaitGroup
    wg.Add(1)
    go func() {
        defer wg.Done()
        var m map[string]int
        m["x"] = 1 // panic in a goroutine
    }()
    wg.Wait()
    fmt.Println("unreachable")
}

No. The whole process crashes with panic: assignment to entry in nil map and a goroutine trace. Panics unwind only the stack of the goroutine that panicked. If that goroutine has no recover of its own, the runtime ends the program, and deferred functions in other goroutines (including main's) never run.

Every goroutine that might panic, especially ones that run user or plugin code or request handlers, needs its own guard:

func safeGo(fn func()) {
    go func() {
        defer func() {
            if r := recover(); r != nil {
                log.Printf("panic: %v\n%s", r, debug.Stack())
            }
        }()
        fn()
    }()
}

net/http recovers panics per request for you, but a goroutine that a handler starts is not covered. Senior answer: recover at goroutine boundaries, log the stack, and turn the panic into an error. Do not quietly swallow it.

More on Tricky Output & Code-Review Puzzles

All 38 Tricky Output & Code-Review Puzzles questions