08 Panic and Reover in Go
(A request to crash the program ...)
1. What is panic
panic
in Go is a built-in function that abruptly stops the execution of the current function when a serious, unrecoverable error occurs.
It's intended to stop execution in an unrecoverable situation (like a bug or critical failure).
2. Some possible scenarios
-
Scenario-1: A Go app that tries to connect to a database right when it starts. If the connection messes up because of some wrong settings, the app just can’t keep running properly.
-
Scenario-2: A program needs to read a config file from the system when it boots up. If that file’s missing, panicking makes sense since there’s no point in going on without it.
-
Scenario-3: An app wants to listen on a TCP port (like a web server). If it can’t get that port because it’s already taken or we don’t have permission, then throwing a panic is a good option.
3. A simple "panic" example
4. More examples
package main
import (
"os"
)
func main() {
file, err := os.Open("config.json")
if err != nil {
panic("Failed to open config file: " + err.Error())
}
defer file.Close()
// Continue with program...
}
Output
package main
import "fmt"
func checkPositive(n int) {
if n <= 0 {
panic("Number must be positive!")
}
}
func main() {
fmt.Println("Checking 5...")
checkPositive(5) // no panic
fmt.Println("5 is positive!")
fmt.Println("Checking -1...")
checkPositive(-1) // will panic here
fmt.Println("-1 is positive!") // This line won't run
}
Output
5. What happens with panic
?
-
Normal execution stops immediately at the point where panic is called.
-
Deferred functions run — Go executes all deferred functions in the current goroutine in reverse order For more info about Deferred functions
-
After all deferred functions finish, if the panic is not recovered (via r), the program:
-
Prints the panic message and a stack trace to the console.
-
Terminates execution — the program crashes.
6. recover
in Go
-
recover() is a built-in function that can catch (recover from) a panic, stopping the program from crashing.
-
It only works if called inside a deferred function. Deferred functions
-
When recover() catches a panic, it returns the panic value (the error/message), and the program resumes normal execution after the deferred function.
Example
package main
import "fmt"
func safeCheck(n int) {
// This is the deferred function
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from panic:", r)
}
}()
// Panic will happen here if n <= 0
if n <= 0 {
panic("Number must be positive!")
}
fmt.Println("Number is", n)
}
func main() {
safeCheck(10)
safeCheck(-5)
fmt.Println("Program continues after panic recovery")
}
7. Multiple "defer" with "recover"
In the following example:
-
Two defer statements are registered: First: the recover() block Second: the fmt.Println("Deferred: End of safeCheck") line
-
Panic is triggered (n <= 0)
-
Go starts unwinding the stack, and executes defers in reverse order:
-
2nd defer runs first: prints Deferred: End of safeCheck
-
1st defer runs second: runs recover(), catches the panic, and prints Recovered from panic:
-
Example:
package main
import "fmt"
func safeCheck(n int) {
defer fmt.Println("Deferred: End of safeCheck") // 2nd defer
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from panic:", r)
}
}() // 1st defer
if n <= 0 {
panic("Number must be positive!")
}
fmt.Println("Number is", n)
}
func main() {
safeCheck(10)
safeCheck(-5)
fmt.Println("Program continues after panic recovery")
}
Number is 10
Deferred: End of safeCheck
Recovered from panic: Number must be positive!
Deferred: End of safeCheck
Program continues after panic recovery
8. Stack unwinding
-In Go (and many other programming languages), function calls are tracked on a call stack — a structure that keeps track of what functions were called.
-
stacks are data structures that work on Last-In-First-Out (LIFO) principle. They are used to call functions in orderly manner.
-
When a panic happens, Go doesn't just stop immediately. It "unwinds the stack", which means:
-
It goes backward through the list of function calls
-
Executes all defer statements in LIFO order
-
Gives each function a chance to clean up or recover
-
-
This process is called stack unwinding.
9. Try-catch vs panic-recover
Go's panic/recover with defer is similar to try/catch in other languages like Java, Python, or JavaScript — but with some key differences in philosophy and mechanics.
Feature | Go (panic /recover ) |
Other languages (try /catch ) |
---|---|---|
Error signal | panic("message") |
throw new Error("message") |
Error handler | recover() inside defer |
catch block |
Cleanup | defer runs during panic stack unwind |
finally block |
Where it's used | Rare, for serious failures | Common for handling expected or unexpected errors |
Control flow | Not meant for normal error handling | Often used for flow control |
Syntax | Manual setup with defer and recover() |
Native try { } catch { } block |