100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Go

panic, recover and defer in Go

Understand Go's defer, panic and recover mechanisms and when they should (and should not) replace normal error handling.

Error HandlingIntermediate9 min readJul 8, 2026
Analogies

Introduction

Go provides defer, panic and recover as a separate mechanism from ordinary error returns, intended for truly exceptional or unrecoverable situations rather than everyday error handling. defer schedules a function call to run when the surrounding function returns, in last-in-first-out (LIFO) order. panic stops the normal execution of a function and begins unwinding the call stack, running any deferred calls along the way. recover, when called inside a deferred function, regains control of a panicking goroutine and stops the unwinding. Idiomatic Go reserves panic/recover for programmer errors or unrecoverable conditions, not for expected failures, which should use the error return pattern instead.

🏏

Cricket analogy: Like a team physio (defer) always being called in at the end of play regardless of outcome, a serious injury (panic) halts the match and unwinds through the innings until team management (recover) steps in, reserved for genuine emergencies not routine dismissals.

Syntax

go
func example() {
    defer fmt.Println("deferred: runs last, when example() returns")

    defer func() {
        if r := recover(); r != nil {
            fmt.Println("recovered from panic:", r)
        }
    }()

    panic("something went badly wrong")
}

Explanation

defer statements are pushed onto a stack tied to the enclosing function; when that function returns (normally or via panic), deferred calls run in LIFO order, making defer ideal for cleanup like closing files or unlocking mutexes. panic(value) immediately stops normal execution, runs deferred calls in the current goroutine, and propagates the panic up the call stack until a deferred function calls recover() or the program crashes with a stack trace. recover() only has an effect when called directly inside a deferred function; it stops the panic from propagating further and returns the value passed to panic. Because panic/recover unwinds the stack and skips normal control flow, Go style reserves it for truly exceptional situations, such as programmer bugs (e.g. index out of range) or unrecoverable startup failures, not for expected, recoverable conditions like a missing file, which should be returned as an error instead.

🏏

Cricket analogy: Like a chain of fielders' end-of-over duties (defer) executing in reverse order they were assigned, a boundary rope incident (panic) runs all pending duties and keeps escalating until the third umpire (recover), called directly from the review booth, stops it, reserved for a genuine crisis not a routine dropped catch.

Example

go
package main

import "fmt"

func safeDivide(a, b int) (result int, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("recovered: %v", r)
        }
    }()

    result = a / b // panics on division by zero
    return result, nil
}

func main() {
    result, err := safeDivide(10, 0)
    if err != nil {
        fmt.Println("Error:", err)
    } else {
        fmt.Println("Result:", result)
    }

    result2, err2 := safeDivide(10, 2)
    fmt.Println(result2, err2)
}

Output

go
Error: recovered: runtime error: integer divide by zero
5 <nil>

Do not use panic/recover as a substitute for normal error returns. Reserve panic for truly unrecoverable situations (like corrupted internal state or programmer bugs), and use error return values for expected, recoverable failure conditions such as invalid input or missing files.

Key Takeaways

  • defer schedules a call to run when the surrounding function returns, in LIFO order.
  • panic stops normal execution and begins unwinding the stack, running deferred calls.
  • recover only works when called directly inside a deferred function.
  • recover stops the panic from propagating and returns the panic's value.
  • panic/recover is for exceptional, unrecoverable situations, not routine error handling.
  • Idiomatic Go still prefers returning an error over panicking for expected failure cases.

Practice what you learned

Was this page helpful?

Topics covered

#Go#GoProgrammingStudyNotes#Programming#PanicRecoverAndDeferInGo#Panic#Recover#Defer#Syntax#StudyNotes#SkillVeris