Panic, defer and Recover in Golang

Go throws panic when there is an error in runtime. The panic stops the flow of the program and produces Error. This post focuses on panic, defer and the recover method in Go.

How panic works in Golang

In Go, panic occurs when at runtime the code is doing something that cannot be done. E.g. accessing index that is out of range. The panic stops the flow os the program. But before doing so it also executes the deferred function calls.

The deferred calls occur when we use the defer keyword before a called function. The function execution goes to last. That means the function will be executed last after all the other program is executed.

Here is a program that throws panic:

package main

func main() {
	panic("Not working!!")
}

The program above throws panic like this:

Go Panic Output
Go Panic Output

Now, when we use a deferred function the panic will allow the deferred function to be executed even when the panic occurs. Here is an example showing that.

package main

import (
	"fmt"
)

func defFunc() {
	fmt.Println("This is a deferred function")
}

func main() {
	defer defFunc()
	panic("Not working!!")
}

Now the output is:

Go Panic Defer
Go Panic and Defer

It can clearly be seen that the deferred function executed before even when the panic stopped the thread. This is a very interesting result that shows us that we can recover from a panic preemptively using a deferred function and thus avoiding the panic completely.

In the above example, even if we remove the “defer” keyword, the output will be the same. It’s because there is no recover() method present in the deferred function. Let’s see how the deferred function and recover() work together in case of a panic situation.

The recover method

The recover() method is a way to recover from a panicking go thread. The function must be implemented inside a deferred function so that it gets executed before the panic stops the thread.

The code below shows how to use the recover function inside a deferred function.

package main

import (
	"fmt"
)

func defFunc() {
	fmt.Println("This is a deferred function")
	
	if r := recover(); r != nil {
		fmt.Println("Recovered from panic that is: ", r)
	}
}

func main() {
	defer defFunc()
	panic("Not working!!")
}

When we see the output we see that the panic is gone and we have recovered the execution thread from the panic.

Go Panic Recover 1
Go Panic Recover

As expected, there are no panics in the output. Note that the defer function must be called before the panic is raised.

Uses of panic and recover

The panic function is a built-in function that can be used when we want to stop the execution due to some unexpected runtime behavior. The recover function is used when we want to regain control of the panicking go thread or goroutine. These two functions can be used simultaneously to create a more concise program in Go.