Error handling in Rust

Macros, “Magic,” and Readability

  • Several commenters express fatigue with heavy macro use in Rust, especially for errors; they prefer explicit enums and structs they can see and reason about.
  • Macros are seen as valuable for cutting boilerplate, but overuse is likened to dynamic-language “magic” that obscures control flow and types, making code harder to debug and understand.
  • IDE “go to definition” mitigates some pain, but people still prefer non-macro declarations where possible.

Rust’s Error Model vs Exceptions and Panics

  • One camp argues Rust “botched” error handling and should have had only panics/exceptions with rich context and a no_panic-style annotation, similar to Java/Python.
  • Others strongly defend Result/Option and explicit error propagation as solving long‑standing problems of unchecked/checked exceptions (non-local control flow, undocumented throws, fragile refactors).
  • There is disagreement over performance: some say unwinding/stack metadata is too expensive for Rust’s low-level goals; critics respond that this is an implementation choice, not inherent to exceptions.

Granularity of Error Types

  • Status quo of “one error type per module/library” is criticized; multiple commenters advocate “one error type per function/action” for precise documentation of what can fail.
  • This approach improves local reasoning and refactor safety but can be painful: adding a new variant forces updates up the call stack and raises composition issues when different functions fail in overlapping ways.
  • Others prefer coarser errors (e.g., generic IO errors) or wrapper/envelope errors, deciding carefully when to discard or aggregate information.

Crates and Patterns: anyhow, thiserror, snafu, etc.

  • anyhow is favored for applications needing a single, flexible error type; many see it as Rust’s de-facto “exceptions.”
  • thiserror and snafu are popular for structured, per-function or per-module enums; snafu’s contextual chaining is praised.
  • Some lament that such fundamental patterns rely on third‑party macros and boilerplate instead of being built into std/core.

Type System and Union Ideas

  • Several people wish Rust had proper union or open sum types to reduce ceremony around error combinations.
  • Others argue naive unions would hurt inference, ergonomics, and performance in a language with pervasive expression typing and monomorphization.

Comparisons and Overall Sentiment

  • Comparisons made to Go, C++, Python, TS, Zig, Java checked exceptions, and Boost.System; opinions differ on which models “got it right.”
  • Many find Rust’s model better than C++/Go but still not “final,” with ongoing tension between explicitness, ergonomics, performance, and macro-induced complexity.