How to Catch Panics in Go

Jay Singh Feb 02, 2024
  1. Catch Panics in Go
  2. Recover Panics in Go
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!