In this tutorial, you will learn about recovery and panic in Golang. Before starting this tutorial make sure you know about the concept of panic which we discussed in our last tutorial.
A recover function is a built-in function used to recover from a panicking situation in the Go programming language. So even if a panic occurs in a go program it is able to recover from that panic and continue its normal execution. This is the significance of the keyword recover.
Let us start to learn through a panicking program given below
package main
import "fmt"
func main() {
fmt.Println("lets learn about recover() in golang")
Panicfunc()
fmt.Println("learned all about recover() ")
}
func Panicfunc() {
fmt.Println("instruction just before panicking situation")
panic("Panicfunc terminates from execution")
fmt.Println("instruction after panic does not execute")
}
Output:
lets learn about recover() in golang instruction just before paniciking situation panic: Panicfunc terminates from execution goroutine 1 [running]: main.Panicfunc() /tmp/sandbox1636989584/prog.go:13 +0x65 main.main() /tmp/sandbox1636989584/prog.go:7 +0x5b Program exited.
A panic function is an exception in Golang where the program terminates from its normal execution without knowing what to do next by leaving an error message either passed by the programmer as arguments using the inbuilt panic function or by default during runtime.
The given program consists of two functions one is main()
and other is Panicfunc()
.
When the program begins its execution from the main function it executes the first instruction to print let's learn about recover()
in golang.
fmt.Println("lets learn about recover() in golang")
The main function scans the next instruction to execute which is a function called Panicfunc().The control switches to Panicfunc() where a set of instructions are executed. The first instruction which is given below is executed and prints
the instruction just before a panicking situation.
fmt.Println("instruction just before panicking situation")
panic("Panicfunc terminates from execution")
The program terminates with the below instruction when it finds panic function and results in printing that string i.e. panic: Panicfunc terminates from execution and leaves some stack trace.
Let us continue with the same code discussed above but some new codes are added to it.
A new function called Panicrecover is added to the above code in which a predefined recover() function is used.
func Panicrecover() {
if err := recover(); err != nil {
fmt.Println("Recovered from panic \n", err)
}
In order to resume the normal flow of execution, we need to add defer function inside the Panicfunc ().
To understand the significance of defer refer tutorial we have already covered. Recover is useful within deferred functions. So if you want to use Panicrecover function (recover ()) inside panicking function ie in our example Panicfunc you need to call defer function which states
defer Panicrecover()
Let us recap the idea of defer.
Any functions which are deferred (delayed) are known as defer functions which are called just before enclosing the function. In our program, the above-given code will defer the function recover.
In this program when a panic occurs then the Panicfunc is called to recover by calling the Panicrecover function. Inside the Panicrecover function, we have a call to inbuilt recover(), which allows the normal flow of the program. The execution is picked up from the Panicfunc() function which is called by main ().
Let us check the whole code
package main
import "fmt"
func main() {
fmt.Println("lets learn about recover() in golang")
Panicfunc()
fmt.Println("learned all about recover() ")
}
func Panicfunc() {
defer Panicrecover()
fmt.Println("instruction just before panicking situation")
panic("Panicfunc resume execution")
fmt.Println("instruction after panic does not execute")
}
func Panicrecover() {
if err := recover(); err != nil {
fmt.Println("Recovered from panic \n", err)
}
}
Output:
lets learn about recover() in golang instruction just before panicking situation Recovered from panic Panicfunc resume execution learned all about recover() Program exited.
The flow of control in a program
Let us summarize the flow chart given above
Yes, the recover function returns a nil value during normal execution.
Consider the same code discussed above by omitting the panicking situation. Just discard the
panic("Panicfunc resume execution")
The code looks like below
package main
import "fmt"
func main() {
fmt.Println("lets learn about recover() in golang")
Panicfunc()
fmt.Println("learned all about recover() ")
}
func Panicfunc() {
defer Panicrecover()
fmt.Println("instruction just before panicking situation")
fmt.Println("instruction after panic does not execute")
}
func Panicrecover() {
if err := recover(); err != nil {
fmt.Println("Recovered from panic \n", err)
}
}
Output:
lets learn about recover() in golang instruction just before panicking situation instruction after panic does not execute learned all about recover() Program exited.
In the above program, the control flows normally. There is nothing to recover from the recover function, no panicking situation so it returns a nil value.
Better understand the below program with recover function containing an else part that states the recover function returns a nil value.
package main
import "fmt"
func main() {
fmt.Println("lets learn about recover() in golang")
Panicfunc()
fmt.Println("learned all about recover() ")
}
func Panicfunc() {
defer Panicrecover()
fmt.Println("instruction just before paniciking situation")
fmt.Println("instruction after panic does not execute")
}
func Panicrecover() {
if err := recover(); err != nil {
fmt.Println("Recovered from panic \n", err)
} else {
fmt.Println("Recover a nil value :", err)
}
}
Output:
lets learn about recover() in golang instruction just before paniciking situation instruction after panic does not execute Recover a nil value :learned all about recover() Program exited.
Note: