Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

golang recover return value syntax

Tags:

go

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?

like image 667
lang2 Avatar asked Sep 03 '14 07:09

lang2


People also ask

What does Golang recover return?

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.

How do you use panic in Golang?

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.


1 Answers

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
    }
}()
like image 185
VonC Avatar answered Sep 18 '22 09:09

VonC