15.1 Recoverable vs. Unrecoverable Errors

Rust classifies runtime errors into two primary categories:

  1. Recoverable Errors: These are expected issues a program might encounter during normal operation, such as failing to open a file, network timeouts, or invalid user input. The program can typically handle these errors gracefully, perhaps by retrying, using a default value, or reporting the issue. Rust uses the generic Result<T, E> enum to represent outcomes that might be successful (Ok(T)) or result in a recoverable error (Err(E)).
  2. Unrecoverable Errors: These represent serious issues, usually programming errors (bugs), from which the program cannot reliably continue. Examples include accessing an array out of bounds, division by zero, or failing assertions about program state. Continuing execution could lead to undefined behavior, data corruption, or security vulnerabilities. Rust uses the panic! macro to signal unrecoverable errors. By default, a panic unwinds the stack of the current thread and terminates it. If this is the main thread, the program exits.

This explicit, type-system-based distinction contrasts sharply with C. In C, whether a -1 return value signifies a recoverable file-not-found error or an unrecoverable null pointer access often depends solely on documentation and programmer discipline. Rust’s Result forces the programmer to consider recoverable errors at compile time. Panics are reserved for situations where proceeding is deemed impossible or unsafe, turning potential C undefined behavior (like out-of-bounds access) into a defined program termination.