How to Catch Panics in Go
Panic, like an error, occurs during runtime. In other words, panic occurs when an unanticipated circumstance occurs in your Go program, causing the execution to be terminated.
When a particular condition develops, such as out-of-bounds array accesses, panic can occur during runtime. These typical actions are indexing an array beyond its limit, conducting type tests, executing methods on nil pointers, wrongly employing mutexes, and attempting to interact with closed channels.
Most of these scenarios arise from programming errors that the compiler cannot discover while building your software. Because panics provide important information for fixing a problem, developers frequently utilize panics to indicate that they have made mistakes during development.
Let’s look at some examples to catch panics in Golang.
Catch Panics in Go
The program below will print a person’s full name. The fullName
function outputs a person’s complete name.
This method determines if the firstName
and lastName
pointers are null. If it is nil
, the function invokes panic with an appropriate message.
Example 1:
package main
import (
"fmt"
)
func fullName(firstName *string, lastName *string) {
if firstName == nil {
panic("runtime error: first name cannot be nil")
}
if lastName == nil {
panic("runtime error: last name cannot be nil")
}
fmt.Printf("%s %s\n", *firstName, *lastName)
fmt.Println("returned normally from fullName")
}
func main() {
firstName := "Jay"
fullName(&firstName, nil)
fmt.Println("returned normally from main")
}
Output:
panic: runtime error: last name cannot be nil
goroutine 1 [running]:
main.fullName(0x405058?, 0xc0000a2f70?)
/tmp/sandbox3339134150/prog.go:12 +0x114
main.main()
/tmp/sandbox3339134150/prog.go:20 +0x35
The code below shows that the employee
function is called from the main
function. We submit the employee’s name
and age
as input.
When an employee’s age surpasses the retirement age, the employee function goes into panic mode.
Example 2:
package main
func employee(name *string, age int) {
if age > 65 {
panic("Age cannot be greater than retirement age")
}
}
func main() {
empName := "Jay"
age := 73
employee(&empName, age)
}
Output:
panic: Age cannot be greater than retirement age
goroutine 1 [running]:
main.employee(...)
/tmp/sandbox4109873090/prog.go:5
main.main()
/tmp/sandbox4109873090/prog.go:12 +0x27
exit status 2
Recover Panics in Go
The recover
function uses the value of the error to determine whether or not a panic occurred. Because the panic function’s input is an empty interface, it can be any type.
Any interface type, including the empty interface, has a zero value of nil
. As seen in this example, care must be taken to prevent using nil
as an input to panic.
Example:
package main
import (
"fmt"
"log"
)
func main() {
divideByZero()
fmt.Println("Hey, we survived dividing by zero!")
}
func divideByZero() {
defer func() {
if err := recover(); err != nil {
log.Println("panic occurred:", err)
}
}()
fmt.Println(divide(1, 0))
}
func divide(a, b int) int {
if b == 0 {
panic(nil)
}
return a / b
}
Output:
Hey, we survived dividing by zero!