Defer, panic and recover: resources¶
Level: 201 · anyone who wants the primary sources behind this chapter, and the books that cover it
One line: The spec's three short sections say almost everything; the blog post from 2010 says it with examples; the release notes for 1.14, 1.21 and 1.25 hold the three changes that matter.
Primary sources¶
- The Go specification, Defer statements ↗ — arguments evaluated at the
defer, last in, first out, named results modifiable, and which expressions may be deferred. - Handling panics ↗ —
panicandrecover, and the two conditions under whichrecoverreturns nil. - Run-time panics ↗ — a run-time error panics with a value that implements
runtime.Error. - Terminating statements ↗ — why a function may end in
panicand not in a call to a function that panics. panic↗ andrecover↗ in packagebuiltin.runtime.Goexit↗,runtime.Error↗,runtime.PanicNilError↗, and theruntimeenvironment variables ↗ forGOTRACEBACK.os.Exit↗ — deferred functions are not run;log.Fatal↗ —Printfollowed byos.Exit(1).- Defer, Panic, and Recover ↗ — Andrew Gerrand, the Go blog, 2010: the three rules of
deferand therecoverexample this chapter's first three lessons follow. - Effective Go, Defer ↗, Panic ↗ and Recover ↗ — the
trace/unidiom, the advice against panicking in a library, and theregexppackage'srecoveraround its parser. - Go 1.14 release notes, Runtime ↗ —
deferat almost zero overhead; and the design document Low-cost defers through inline code, and extra funcdata to manage the panic case ↗ — the limits (eight defers, none in a loop) and the measurements. - Go 1.19 release notes, os ↗ — the open-file soft limit raised to the hard limit at startup, which lets a loop of deferred
Closecalls run further before it fails. - Go 1.21 release notes, Changes to the language ↗ —
panic(nil)becomes a*runtime.PanicNilError;GODEBUG=panicnil=1. - Go 1.25 release notes, Runtime ↗ —
[recovered, repanicked]replaces the repeated panic text. go vet↗ and the analyzers this chapter runs:lostcancel↗,unreachable↗,unusedresult↗,copylocks↗.- Outside the distribution, named on the vet page and not run: staticcheck SA5001 ↗ and SA9001 ↗, revive's
deferrule ↗, go-critic'sdeferInLoop↗, errcheck ↗.
Books¶
- Alan A. A. Donovan and Brian W. Kernighan, The Go Programming Language (Addison-Wesley, 2015), chapter 5, "Functions" — sections 5.8, "Deferred Function Calls" (the loop-of-files case and the helper fix, deferred closures and named results), 5.9, "Panic", and 5.10, "Recover" (recovering selectively, by a private panic type).
- Jon Bodner, Learning Go, 2nd ed. (O'Reilly, 2024), chapter 5, "Functions" — the section "defer"; chapter 9, "Errors" — the section "panic and recover".
- Matt Butcher, Matt Farina and Nathan Kozyra, Go in Practice, 2nd ed. (Manning, 2025), chapter 4, "Handling errors and panics" — section 4.3, "The panic system": "Differentiating panics from errors", "Working with panics", "Recovering from panics", "Capturing panics with defer" and "Handling panics on goroutines".
- Adam Freeman, Pro Go (Apress, 2022), chapter 8, "Defining and Using Functions" — "Using the defer Keyword"; chapter 15, "Error Handling" — "Dealing with Unrecoverable Errors": "Recovering from Panics", "Panicking After a Recovery" and "Recovering from Panics in Go Routines".
- Miki Tebeka, Effective Go Recipes (Pragmatic Bookshelf, 2024), chapter 8, "Working with Errors" — Recipe 43, "Handling Panics", and Recipe 44, "Handling Panics in Goroutines".
- Katherine Cox-Buday, Concurrency in Go (O'Reilly, 2017), and James Cutajar, Learn Concurrent Programming with Go (Manning, 2024), use
deferthroughout and have no section on it; for a panic inside a goroutine, A panic ends the whole program is this library's page.
Not on the shelf¶
- Teiva Harsanyi, 100 Go Mistakes and How to Avoid Them (Manning, 2022) — 100go.co ↗ — several of its mistakes are this chapter's lessons: how
deferarguments and receivers are evaluated,deferin a loop, an ignoredCloseerror. - Bartłomiej Płotka, Efficient Go (O'Reilly, 2022) — efficientgo.com ↗ — for measuring what a
defercosts rather than assuming it.
Talks and videos¶
- Dave Cheney, "Don't just check errors, handle them gracefully" — GoCon Spring 2016, Tokyo; the text is on his blog, dave.cheney.net ↗: why a library returns errors rather than panicking, and how to wrap them.
- No GopherCon talk devoted to
deferitself is listed here; the design document above is the primary account of open-coded defers, and its authors' measurements are the ones to cite.
Read with care¶
- "
deferis slow, keep it out of hot paths." True before Go 1.14, when a deferred call cost an allocation and tens of nanoseconds; since then most defers are open-coded and the advice is stale — What adefercosts. Adeferin a loop is still heap-allocated. - "
recover()returns nil forpanic(nil), so you cannot tell it from no panic." True before Go 1.21; nowpanic(nil)recovers as a*runtime.PanicNilErrorunless the module'sgoline is 1.20 or earlier —recoverworks only in the deferred call. - Panic output in older books and posts shows
panic: X [recovered]and thenpanic: Xon a second line; Go 1.25 printspanic: X [recovered, repanicked]. defer recover()turns up in forum answers as a one-liner; it compiles and does nothing.recoverinmainas a safety net for the whole program coversmain's goroutine only — A panic ends the whole program.- Pro Go's section "Deferring Execution of a Function" (chapter 19, "Dates, Times, and Durations") is about
time.AfterFunc, notdefer; thedefersection is the one in chapter 8.
Checked 2026-09-23.