Skip to main content
We learned that the idiomatic way of handling abnormal conditions in a Go program is using errors. While errors are sufficient for most cases, there are some situations where the program cannot continue. In those cases, we can use the built-in panic function.

Panic

func panic(interface{})
The panic is a built-in function that stops the normal execution of the current goroutine. When a function calls panic, the normal execution of the function stops immediately and the control is returned to the caller. This is repeated until the program exits with the panic message and stack trace.
We will discuss goroutines later in the course.
Let’s see how we can use the panic function:
package main

func main() {
	WillPanic()
}

func WillPanic() {
	panic("Woah")
}
And if we run this, we can see panic in action:
$ go run main.go
panic: Woah

goroutine 1 [running]:
main.WillPanic(...)
        .../main.go:8
main.main()
        .../main.go:4 +0x38
exit status 2
As expected, our program printed the panic message, followed by the stack trace, and then it was terminated. So, the question is, what to do when an unexpected panic happens?

Recover

It is possible to regain control of a panicking program using the built-in recover function, along with the defer keyword.
func recover() interface{}
Let’s try an example by creating a handlePanic function. Then, we can call it using defer:
package main

import "fmt"

func main() {
	WillPanic()
}

func handlePanic() {
	data := recover()
	fmt.Println("Recovered:", data)
}

func WillPanic() {
	defer handlePanic()

	panic("Woah")
}
$ go run main.go
Recovered: Woah
As we can see, our panic was recovered and now our program can continue execution.
panic and recover can be considered similar to the try/catch idiom in other languages. But we should avoid panic and recover and use errors when possible.

Use Cases

If so, then when should we use panic? There are two valid use cases for panic:

An unrecoverable error

This is a situation where the program cannot simply continue its execution. For example, reading a configuration file which is important to start the program. There is nothing else to do if the file read itself fails.

Developer error

This is the most common situation. For example, dereferencing a pointer when the value is nil will cause a panic.
Use panic sparingly and prefer explicit error handling for most scenarios.

Build docs developers (and LLMs) love