Defer, Panic, and Recover
4 Aug 2010
Tags: defer, panic, recover, technical, function

Andrew Gerrand

* Introduction

Go has the usual mechanisms for control flow:
if, for, switch, goto.
It also has the go statement to run code in a separate goroutine.
Here I'd like to discuss some of the less common ones:
defer, panic, and recover.

A *defer*statement* pushes a function call onto a list.
The list of saved calls is executed after the surrounding function returns.
Defer is commonly used to simplify functions that perform various clean-up actions.

For example, let's look at a function that opens two files and copies the contents of one file to the other:

	func CopyFile(dstName, srcName string) (written int64, err error) {
	    src, err := os.Open(srcName)
	    if err != nil {
	        return
	    }

	    dst, err := os.Create(dstName)
	    if err != nil {
	        return
	    }

	    written, err = io.Copy(dst, src)
	    dst.Close()
	    src.Close()
	    return
	}

This works, but there is a bug. If the call to os.Create fails,
the function will return without closing the source file.
This can be easily remedied by putting a call to src.Close before the second return statement,
but if the function were more complex the problem might not be so easily
noticed and resolved.
By introducing defer statements we can ensure that the files are always closed:

	func CopyFile(dstName, srcName string) (written int64, err error) {
	    src, err := os.Open(srcName)
	    if err != nil {
	        return
	    }
	    defer src.Close()

	    dst, err := os.Create(dstName)
	    if err != nil {
	        return
	    }
	    defer dst.Close()

	    return io.Copy(dst, src)
	}

Defer statements allow us to think about closing each file right after opening it,
guaranteeing that, regardless of the number of return statements in the function,
the files _will_ be closed.

The behavior of defer statements is straightforward and predictable. There are three simple rules:

1. _A_deferred_function's_arguments_are_evaluated_when_the_defer_statement_is_evaluated._

In this example, the expression "i" is evaluated when the Println call is deferred.
The deferred call will print "0" after the function returns.

	func a() {
	    i := 0
	    defer fmt.Println(i)
	    i++
	    return
	}

2. _Deferred_function_calls_are_executed_in_Last_In_First_Out_order_after_the_surrounding_function_returns._

This function prints "3210":

	func b() {
	    for i := 0; i < 4; i++ {
	        defer fmt.Print(i)
	    }
	}

3. _Deferred_functions_may_read_and_assign_to_the_returning_function's_named_return_values._

In this example, a deferred function increments the return value i _after_
the surrounding function returns.
Thus, this function returns 2:

	func c() (i int) {
	    defer func() { i++ }()
	    return 1
	}

This is convenient for modifying the error return value of a function; we will see an example of this shortly.

*Panic* is a built-in function that stops the ordinary flow of control and begins _panicking_.
When the function F calls panic, execution of F stops,
any deferred functions in F are executed normally,
and then F returns to its caller.
To the caller, F then behaves like a call to panic.
The process continues up the stack until all functions in the current goroutine have returned,
at which point the program crashes.
Panics can be initiated by invoking panic directly.
They can also be caused by runtime errors,
such as out-of-bounds array accesses.

*Recover* is a built-in function that regains control of a panicking goroutine.
Recover is only useful inside deferred functions.
During normal execution, a call to recover will return nil and have no other effect.
If the current goroutine is panicking, a call to recover will capture the
value given to panic and resume normal execution.

Here's an example program that demonstrates the mechanics of panic and defer:

	package main

	import "fmt"

	func main() {
	    f()
	    fmt.Println("Returned normally from f.")
	}

	func f() {
	    defer func() {
	        if r := recover(); r != nil {
	            fmt.Println("Recovered in f", r)
	        }
	    }()
	    fmt.Println("Calling g.")
	    g(0)
	    fmt.Println("Returned normally from g.")
	}

	func g(i int) {
	    if i > 3 {
	        fmt.Println("Panicking!")
	        panic(fmt.Sprintf("%v", i))
	    }
	    defer fmt.Println("Defer in g", i)
	    fmt.Println("Printing in g", i)
	    g(i + 1)
	}

The function g takes the int i, and panics if i is greater than 3,
or else it calls itself with the argument i+1.
The function f defers a function that calls recover and prints the recovered
value (if it is non-nil).
Try to picture what the output of this program might be before reading on.

The program will output:

	Calling g.
	Printing in g 0
	Printing in g 1
	Printing in g 2
	Printing in g 3
	Panicking!
	Defer in g 3
	Defer in g 2
	Defer in g 1
	Defer in g 0
	Recovered in f 4
	Returned normally from f.

If we remove the deferred function from f the panic is not recovered and
reaches the top of the goroutine's call stack,
terminating the program.
This modified program will output:

	Calling g.
	Printing in g 0
	Printing in g 1
	Printing in g 2
	Printing in g 3
	Panicking!
	Defer in g 3
	Defer in g 2
	Defer in g 1
	Defer in g 0
	panic: 4

	panic PC=0x2a9cd8
	[stack trace omitted]

For a real-world example of *panic* and *recover*,
see the [[https://golang.org/pkg/encoding/json/][json package]] from the
Go standard library.
It encodes an interface with a set of recursive functions.
If an error occurs when traversing the value,
panic is called to unwind the stack to the top-level function call,
which recovers from the panic and returns an appropriate error value (see
the 'error' and 'marshal' methods of the encodeState type in [[https://golang.org/src/pkg/encoding/json/encode.go][encode.go]]).

The convention in the Go libraries is that even when a package uses panic internally,
its external API still presents explicit error return values.

Other uses of *defer* (beyond the file.Close example given earlier) include releasing a mutex:

	mu.Lock()
	defer mu.Unlock()

printing a footer:

	printHeader()
	defer printFooter()

and more.

In summary, the defer statement (with or without panic and recover) provides
an unusual and powerful mechanism for control flow.
It can be used to model a number of features implemented by special-purpose
structures in other programming languages. Try it out.
