Introduction
In Go, the panic
function is used to indicate that something has gone seriously wrong and that the program cannot continue to run normally. When a panic
is called, it immediately stops the execution of the current function and begins to unwind the stack, running any deferred functions along the way. In this chapter, you will learn the basics of using panic
, when to use it, and how to recover from a panic using the recover
function.
Using Panic
The panic
function can be called with a string or an error that describes the error condition. It is typically used for unrecoverable errors, such as those indicating a programmer error or a situation where the program cannot proceed.
Example: Basic Usage of Panic
Example:
package main
import "fmt"
func main() {
fmt.Println("Start of the program")
panic("Something went wrong")
fmt.Println("End of the program") // This line will not be executed
}
Output:
Start of the program
panic: Something went wrong
goroutine 1 [running]:
main.main()
/path/to/file.go:6 +0x39
exit status 2
When to Use Panic
- Unrecoverable errors: Use
panic
when the program encounters an error that it cannot recover from, such as a corrupted state or a violation of a fundamental assumption. - Programming errors: Use
panic
to indicate programmer errors, such as accessing out-of-bounds slices or dereferencingnil
pointers.
Recovering from Panic
The recover
function is used to regain control of a program that is panicking. It can only be called from within a deferred function. When called, it stops the panic and returns the value passed to the panic
call.
Example: Using Recover to Handle Panic
Example:
package main
import "fmt"
func main() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from panic:", r)
}
}()
fmt.Println("Starting the program")
panic("Something went wrong")
fmt.Println("End of the program") // This line will not be executed
}
Output:
Starting the program
Recovered from panic: Something went wrong
Combining Panic and Recover
Combining panic
and recover
allows you to handle serious errors gracefully without crashing the entire program.
Example: Graceful Error Handling
Example:
package main
import "fmt"
func main() {
fmt.Println("Starting the program")
safeDivision(10, 2)
safeDivision(10, 0)
fmt.Println("Program continues after panic recovery")
}
func safeDivision(a, b int) {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in safeDivision:", r)
}
}()
if b == 0 {
panic("cannot divide by zero")
}
result := a / b
fmt.Println("Result of division:", result)
}
Output:
Starting the program
Result of division: 5
Recovered in safeDivision: cannot divide by zero
Program continues after panic recovery
Defer, Panic, and Recover
When panic
is called, the current function stops executing and starts to unwind the stack, running any deferred functions along the way. If a deferred function calls recover
, the panic stops, and the program can continue executing normally.
Example: Defer, Panic, and Recover
Example:
package main
import "fmt"
func main() {
fmt.Println("Starting the program")
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from panic:", r)
}
}()
defer fmt.Println("Deferred call")
panic("Something went wrong")
fmt.Println("End of the program") // This line will not be executed
}
Output:
Starting the program
Deferred call
Recovered from panic: Something went wrong
Conclusion
The panic
function in Go is used for handling serious errors that cannot be recovered from. It stops the execution of the current function and begins to unwind the stack, running deferred functions along the way. By using recover
within deferred functions, you can regain control of your program and handle panics gracefully. Understanding when and how to use panic
and recover
is essential for writing robust and resilient Go programs.