tezvyn:

Go's Panic/Recover: For Exceptional Errors Only

AI-drafted, machine-checkedSource: go.devadvanced

Go's panic/recover is a last-resort error mechanism, not a try/catch replacement. A panic unwinds a goroutine's stack until a recover in a defer'd function catches it. It's used to keep a server alive when one request fails catastrophically.

WHY IT EXISTS Go's design prefers explicit error return values for predictable failures. However, some situations are truly exceptional and unrecoverable, like a nil pointer dereference or an index out of bounds. panic provides a mechanism to immediately stop execution within a goroutine to prevent further damage from a corrupted state.

THE MENTAL MODEL Think of panic and recover as a limited, goroutine-specific exception system, not a general-purpose try/catch. A panic is like throwing a fatal exception. A defer statement acts like a finally block, always executing as the function exits (either normally or during a panic). A recover call inside that defer is the catch block that can stop the program from crashing.

HOW IT WORKS When panic is called, normal execution halts. The runtime begins unwinding that goroutine's call stack. For each function frame it unwinds, it executes any deferred calls in Last-In, First-Out (LIFO) order. If a deferred function calls recover, the panic is caught. recover returns the value passed to panic and normal execution resumes. If no recover is called, the panic reaches the top of the goroutine's stack and the entire program crashes. recover is only useful when called directly by a deferred function.

WHEN TO USE IT The main legitimate use is to safeguard a program from crashing due to an unexpected bug in one part. For instance, a web server can wrap each request handler with a defer/recover middleware. If a single handler panics, the server can log the error, send a 500 response to that client, and continue serving other requests unaffected. It's for containing programmer errors, not for handling expected operational failures.

WHEN NOT TO USE IT Never use panic for ordinary error handling or control flow. If a function can fail predictably, like failing to open a file or parse user input, it must return an error value. Using panic for these cases violates Go's idiomatic error handling, making the code confusing, brittle, and difficult for callers to manage. It breaks the function's public API contract.

ONE CANONICAL EXAMPLE Imagine a function that performs a complex calculation which might, due to a bug, attempt to divide by zero. Instead of letting this crash the application, a calling function can use defer to schedule a function that calls recover. If recover returns a non-nil value, it indicates a panic occurred. The deferred function can then log the error and set a named return error variable, converting the catastrophic panic into a manageable error for its caller.

Read the original → go.dev

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.