10/01/2020 - GO
A panic is designed to crash the application which is the default behaviour. However, if you want to prevent this from happening and let your application carry on running as if nothing has happened you will have to use recover
function. The rule is, recover from panics only if you meant to. In short, don't recover every panic by default. Instead, selectively recover by checking the panic type. Note: There is no recovery for conditions such as the application running out of memory.
As shown below, the application crashed.
func main() {
fmt.Println("main: begin")
panic("Main function panicked!")
fmt.Println("main: end")
}
// Output:
// main: begin
// panic: Main function panicked!
//
// goroutine 1 [running]:
// main.main()
// /Users/mysql/Server/Go/src/github.com/inanzzz/client/cmd/client/main.go:4 +0xb3
// exit status 2
As seen below, the application recovered from panic and didn't crash.
func main() {
defer func() {
if p := recover(); p != nil {
fmt.Println("main: recovered from panic")
}
}()
fmt.Println("main: begin")
panic("Main function panicked!")
fmt.Println("main: end")
}
// Output:
// main: begin
// main: recovered from panic
As seen below, the application recovered from good
panic type but not the others.
type good struct {}
type bad struct {}
func main() {
defer func() {
switch p := recover(); p {
case nil:
case good{}:
log.Printf("recovered from %T\n", p)
case bad{}:
panic(p)
default:
panic(p)
}
}()
fmt.Println("main: begin")
//panic(good{})
//panic(bad{})
//panic("something else")
fmt.Println("main: end")
}
// Output for no panic at all.
// main: begin
// main: end
// Output when panic(good{}) is enabled.
// main: begin
// 2020/01/10 22:27:54 recovered from main.good
// Output when panic(bad{}) is enabled.
// main: begin
// ...
// /Users/inanzzz/Server/Go/src/github.com/inanzzz/client/cmd/client/main.go:11 +0xda
// ...
// exit status 2
// Output when panic("something else") is enabled.
// main: begin
// ...
// /Users/inanzzz/Server/Go/src/github.com/inanzzz/client/cmd/client/main.go:13 +0xda
// ...
// exit status 2