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:
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:
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.
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.