Panic recovery regains control after a Go panic by placing recovery logic in a deferred function. During stack unwinding, Go executes deferred functions before the parent function returns, whether normally or because of a panic. section 4.3.3 section 4.3.4
Listing 4.14 Recovering from a panic
package main
import (
"errors"
"fmt"
)
func main() {
defer func() { #1
if err := recover(); err != nil { #1
fmt.Printf("Trapped panic: %s (%T) #1
\n", err, err) #1
} #1
}() #1
yikes() #2
}
func yikes() {
panic(errors.New("Something bad happened.")) #3
}
A complete pattern defers an anonymous closure, calls recover, checks for a non-nil result, and reports the panic value and its type. section 4.3.4
The deferred closure is defined immediately but runs later, at the end of the surrounding function’s scope. recover returns the value supplied to panic, or nil when no panic is active. A panic created with errors.New can therefore be reported as an error value. section 4.3.4
Use the same deferred-function mechanism for related control-flow and cleanup tasks:
- Schedule cleanup such as closing files or sockets and releasing database handles. section 4.3.3
- Capture variables from the surrounding scope: a deferred closure observes a variable’s later value, while a variable declared in a narrower scope is unavailable. section 4.3.4
- Recover at a function boundary when a called function panics, allowing the surrounding program to continue instead of crashing. section 4.3.4
