Go by Example: Recover

A recover means recovering from a panic, either from a “business” or “built-in” panic.\n We want to recover if we want to handle a panic, stopping it from propagating upwards.

package main
import (
    "fmt"
)
func main() {
    recoverFromBuiltInPanic(10)
    fmt.Println()
    recoverFromCustomPanic(-1)
}

defer is defined.

func recoverFromBuiltInPanic(i int) {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered. Error:\n", r)
        }
    }()
    var a [5]int
    fmt.Printf("Getting index %d"+
        " of array of len %d...\n", i, len(a))
    fmt.Printf("Item in index %d: %d", i, a[i])
}

defer is defined.

func recoverFromCustomPanic(i int) {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered. Error:\n", r)
        }
    }()
    fmt.Printf("About to process i=%d\n", i)
    if i < 0 {
        panic(fmt.Errorf("Accepting only"+
            " non-negative numbers but received %d", i))
    }
    fmt.Printf("Doing something with %d\n", i)
}

Running this program will exit correctly, even though panic was invoked in two methods. The recover is responsible for recovering from panics.

$ go run recover.go
Getting index 10 of array of len 5...
Recovered. Error:
 runtime error: index out of range [10] with length 5

Note that, in Go it is idiomatic to use error-indicating return values wherever possible.

About to process i=-1
Recovered. Error:
 Accepting only non-negative numbers but received -1

Next example: Collection Functions.