Go > Error Handling > Panic and Recover > Recovering from panic
Recovering from Panic in Go
This snippet demonstrates how to use the `recover` function in Go to gracefully handle panics and prevent program termination.
Introduction to Panic and Recover
Go's panic mechanism is similar to exceptions in other languages. A panic occurs when the program encounters an unrecoverable error at runtime. When a panic happens, the program normally halts. However, Go provides a built-in function called `recover` that allows you to regain control of a panicking goroutine and prevent the program from crashing. `recover` only works when called directly within a deferred function.
Code Example: Recovering from a Panic
This code demonstrates a function `mightPanic` that could potentially cause a panic (in this case, a division by zero). The `recoverFromPanic` function is defined to handle any panics that occur within `mightPanic`. Importantly, `recoverFromPanic` is called using `defer`, ensuring it's executed even if a panic occurs. If a panic happens, `recover()` will return the value passed to `panic()`, otherwise it returns `nil`. The program will then print a message indicating it recovered and continues execution.
package main
import (
"fmt"
)
func recoverFromPanic() {
if r := recover(); r != nil {
fmt.Println("Recovered from panic:", r)
}
}
func mightPanic(input int) {
defer recoverFromPanic()
fmt.Println("Starting mightPanic with input:", input)
if input == 0 {
panic("Division by zero!")
}
result := 100 / input
fmt.Println("Result:", result)
}
func main() {
mightPanic(10)
mightPanic(0)
mightPanic(5)
fmt.Println("Program continues after panics are handled.")
}
Explanation of the Code
1. **`recoverFromPanic` Function:** This function uses `recover()` to check if a panic occurred. If `recover()` returns a non-nil value, it means a panic happened, and we can handle it here. In this case, we print a message to the console. 2. **`mightPanic` Function:** This function simulates a situation that could lead to a panic. The `defer recoverFromPanic()` line ensures that `recoverFromPanic` is always executed before the function returns, regardless of whether a panic occurs. 3. **`panic` Function:** If `input` is 0, the code calls `panic("Division by zero!")`. This triggers a panic, which is then caught by the deferred `recoverFromPanic` function. 4. **`main` Function:** The `main` function calls `mightPanic` with different inputs to demonstrate how the `recover` mechanism works. Note that the program continues to execute even after a panic is recovered from.
Concepts Behind the Snippet
The core concepts here are `defer`, `panic`, and `recover`. `defer` schedules a function call to be run after the surrounding function returns. `panic` initiates a runtime error, stopping normal execution. `recover` allows a program to regain control after a panic.
Real-Life Use Case Section
Recovering from panics is particularly useful in server applications. Imagine a web server handling multiple requests concurrently. If one request causes a panic, you don't want the entire server to crash. By using `recover`, you can catch the panic, log the error, and return an error response to the client, while allowing the server to continue processing other requests. Database connection management and file processing are also excellent use-cases.
Best Practices
Interview Tip
Be prepared to explain the difference between `error` and `panic` in Go. Also, be able to describe how `defer` and `recover` work together to handle panics. Expect questions about when to use `panic` versus returning an `error`.
When to Use `recover`
Use `recover` when you want to prevent a panic from crashing your entire program. This is especially important in long-running processes like servers or background workers.
Alternatives
Instead of using `panic` and `recover` for general error handling, prefer returning explicit `error` values. This makes the error handling more explicit and easier to reason about.
Pros and Cons of Using `recover`
FAQ
-
What happens if I don't use `recover` when a panic occurs?
If a panic occurs and there is no `recover` function in the call stack, the program will terminate and print a stack trace to the console. -
Can I use `recover` outside of a deferred function?
No, `recover` only works when called directly within a deferred function. Calling it outside of a deferred function will always return `nil`. -
Is it good practice to use panic/recover instead of error return for expected errors?
Generally, no. Error returns are preferred for anticipated errors, while panic/recover should be reserved for truly exceptional, unrecoverable situations.