TheDeveloperBlog.com


Golang Recover Built-in: Handle Errors, Panics

Recover. Failure is everywhere. A method might work when we test it. But it is just waiting to fail at the worst moment. Go provides ways to handle errors.


With recover, a built-in method, we get errors and can test them. We must specify a call to recover() in a "defer" method. The Go runtime calls these methods when an error occurs.


First example. Let us begin. This program introduces a hopeless method called "divideByZero." It causes an error to occur whenever it is run.

Defer: In divideByZero we specify a nested "defer" method. In this func we assign err to the result of recover().

And: If err is not nil, we take an action that can repair the program's state and keep it from terminating.

Tip: In this program, if we remove the divide by zero error, the value of "dog" will be printed. And the "defer" func will never be called.

Based on:

Golang 1.4

Golang program that uses recover, defer func

package main

import "fmt"

func divideByZero() {
    // Use this deferred function to handle errors.
    defer func() {
	if err := recover(); err != nil {
	    fmt.Println("HERE")
	    fmt.Println(err)
	    fmt.Println(0)
	}
    }()
    // Cause an error.
    // ... Go will run the defer func above.
    cat := 0
    dog := 10 / cat
    fmt.Println(dog)
}

func main() {
    // Create a divide by zero error and handle it.
    divideByZero()
}

Output

HERE
runtime error: integer divide by zero
0

Panic. This built-in method causes an error to occur. We can handle this error in a defer method that tests the result of recover().

Tip: When panic is called, the stack is unwound. And each method is tested for a defer method.

Recover: The recover() method returns panic's error. In this program, the WRONG message is provided.

Golang program that uses panic, defer and recover

package main

import "fmt"

func explode() {
    // Cause a panic.
    panic("WRONG")
}

func main() {
    // Handle errors in defer func with recover.
    defer func() {
	if err := recover(); err != nil {
	    // Handle our error.
	    fmt.Println("FIX")
	    fmt.Println("ERR", err)
	}
    }()
    // This causes an error.
    explode()
}

Output

FIX
ERR WRONG

With recover, defer and panic we handle errors in Go programs. This is an alternative to exception handling (like try and catch in other languages).