I'm trying to understand how to recover from panic situation. Normally, something like this will do:
if r := recover(); r != nil {
fmt.Println("Recovered in f", r)
}
I can understand those much. But I've seen code snippet like the following:
if r, ok := recover().(error); ok {
fmt.Println("Recovered in f", r)
}
What's the .(error)
part doing?
The recover function returns the value which was passed to the panic function. Therefore it is a good practice to check the return value of the recover function.
In Go language, panic is just like an exception, it also arises at runtime. Or in other words, panic means an unexpected condition arises in your Go program due to which the execution of your program is terminated.
It is a type assertion which check if the error recovered is of a certain type.
It that type assertion fails, that causes a run-time error that continues the stack unwinding as though nothing had interrupted it.
This is useful when you define a local MyError
type for error, and you want to recover only from that type.
You can see an example in "Error handling and Go"
Client code can test for a net.Error with a type assertion and then distinguish transient network errors from permanent ones.
For instance, a web crawler might:
- sleep and retry when it encounters a temporary error
- and give up otherwise.
if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
time.Sleep(1e9)
continue
}
if err != nil {
log.Fatal(err)
}
If you have several types of error you want to recover, you can use a type switch is in "Golang: returning from defer"
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in f", r)
// find out exactly what the error was and set err
switch x := r.(type) {
case string:
err = errors.New(x)
case error:
err = x
default:
// Fallback err (per specs, error strings should be lowercase w/o punctuation
err = errors.New("unknown panic")
}
// invalidate rep
rep = nil
// return the modified err and rep
}
}()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With