Generic Panic Recovering in Go Programs
When working with Go routines, there may be instances where you want to catch and handle crashes or panics that occur within them, potentially for reporting to an error-reporting server like Sentry or Raygun. However, it's crucial to note that a goroutine cannot recover from a panic in another goroutine.
Idiomatic Approach
The idiomatic way to handle this is to inject code into the function that is launched as a goroutine. This involves utilizing a deferred function that calls recover(), which provides the ability to recover from a panicking state.
Consider the following example:
go func() { defer func() { if r := recover(); r != nil { fmt.Println("Caught:", r) } }() panic("catch me") }()
This code will output the relevant panic message when executed.
While it's impractical to implement this approach in every goroutine you launch, you can simplify the process by defining a named function that includes the recovery functionality, and call that function within your goroutine (with a deferred call).
func logger() { if r := recover(); r != nil { fmt.Println("Caught:", r) } }
By calling this function within a deferred closure, you can handle panic situations in a concise manner.
go func() { defer logger() panic("catch me") }()
Wrapper Function
For greater convenience, you can create a wrapper function that takes the actual function as input and manages the panic recovery process. This wrapper function can be utilized as follows:
func wrap(f func()) { defer func() { if r := recover(); r != nil { fmt.Println("Caught:", r) } }() f() }
Using this wrapper simplifies the panic handling process even further:
go wrap(func() { panic("catch me") })
Additional Considerations
The example codes provided demonstrate situations where a goroutine is launched within the wrap() function. This allows the caller to determine whether a new goroutine is necessary by preceding the wrap() call with the go keyword. However, the wrap() function can also be used to protect the execution of arbitrary functions that are passed as input, even if you don't want to run them concurrently in a new goroutine.
The above is the detailed content of How Can I Recover from Panics in Go Goroutines?. For more information, please follow other related articles on the PHP Chinese website!