15.7 Summary

Rust elevates error handling from a matter of convention (as often in C) to a core language feature integrated with the type system.

  • Clear Distinction: It separates recoverable errors (Result<T, E>) from unrecoverable bugs/invariant violations (panic!).
  • Compile-Time Safety: Result<T, E> forces callers to acknowledge and handle potential failures, preventing accidentally ignored errors common in C.
  • Result<T, E>: The standard mechanism for functions that can fail recoverably. Handled via match, basic checks (is_ok/is_err), combinators, or propagated via ?.
  • panic!: Reserved for unrecoverable errors. Causes stack unwinding (or abort) and thread termination. Avoid in library code for expected failures.
  • ? Operator: Enables concise and readable propagation of Err values up the call stack within functions returning Result. Replaces manual match blocks for error checking and early return.
  • Multiple Error Types: Managed using custom error enums (best for libraries), Box<dyn Error> (simpler, for applications), or helper crates like thiserror and anyhow.
  • Best Practices: Emphasize returning Result, providing context, propagating errors, and using panic! (and unwrap/expect) judiciously.

By making error states explicit and requiring they be handled, Rust helps developers write more robust, reliable, and maintainable software compared to traditional approaches relying solely on programmer discipline.