The cost of Go's panic and recover

Exceptions / panics as control flow

  • Some participants defend using exceptions (or panics) to short‑circuit deep recursion or search, arguing the alternative is manually threading booleans or error flags through every stack frame.
  • Others counter that panics in Go are explicitly not meant as general control flow or error propagation, unlike typical exception systems.

Go’s error handling ergonomics

  • Widespread frustration with if err != nil boilerplate; some feel early promises that higher‑level patterns would emerge never materialized.
  • Others defend it as explicit, legible control flow, preferring it over “magic” constructs or heavily abstracted error monads.
  • There’s disagreement on community culture: some see resistance to acknowledging flaws (generics, errors); others say the ecosystem is actively exploring better error syntaxes and patterns.

Semantics and use of panic/recover

  • Strong view from several commenters: panics are for truly unrecoverable/buggy states (nil deref, impossible invariants), not normal failures like I/O errors; panic used like exceptions is called an antipattern.
  • Counter‑view: many real systems prefer to catch panics at boundaries, log/emit telemetry, and continue serving other work; killing the whole process is often seen as too harsh.
  • Debate over whether “unrecoverable” conditions really exist in most software, and how that relates to concepts like the halting problem.

Where recover() is actually used

  • Many report rarely using recover directly; common patterns are:
    • HTTP or gRPC middleware to convert panics into 500s and logs.
    • Wrapping goroutines to prevent a single request/task panic from crashing the process.
    • Parser implementations and some stdlib components that still use panic/recover internally.
  • Pain point: no global catch‑all for panics across goroutines; you must wrap each goroutine or handle it at the process/container level.

Go vs Rust and other models

  • Rust’s Result/Option plus ? are praised for eliminating silent error‑ignoring, though some argue the functional style (map, or_else) feels too abstract for many teams.
  • Go’s ability to ignore error returns (especially via multiple assignment quirks) is seen as dangerous; linters help but are not universally enforced.

Performance and best practices

  • Some claim that in certain patterns, panic+recover at a high level can outperform error checks at every call.
  • Several commenters propose practical rules:
    • Only panic in main or at startup, or provide paired Foo/MustFoo APIs.
    • Centralize recovery for request handlers and goroutine entrypoints; otherwise, return errors and wrap them with contextual messages.