ProgrammingSystem Developer

Describe how errors are handled in Rust. What is the difference between panic!, Result, and Option? Why are exceptions not used in Rust?

Pass interviews with Hintsage AI assistant

Answer

In Rust, there are no traditional exceptions like in Java or C++; instead, the wrapper types Result and Option are used for returning errors.

  • Result<T, E> — holds either a value (Ok(T)) or an error (Err(E)). It is typically used for operations that may fail (e.g., file I/O).

  • Option<T> — for optional values: either Some(T) or None, without error information. Example:

fn divide(x: f64, y: f64) -> Option<f64> { if y == 0.0 { None } else { Some(x / y) } }
  • panic! — triggers an emergency shutdown, formatted as "fatal error" or "assert". It should only be used for invariant violations, not for handling user errors.

Rust does not have exceptions in the try/catch style to ensure a transparent, managed error flow without requiring a garbage collector or unwind engine to maintain exceptions.

Trick Question

Why should panic! not be used for normal error handling?

Answer: panic! terminates the execution flow, does not allow recovery, and leads to unwinding/abort. If errors are returned through Result, the calling side can handle them. Example:

fn foo() -> Result<(), String> { Err("Smth went wrong".to_string()) } // instead of fn foo() { panic!("Smth went wrong"); }

Examples of real errors due to ignorance of the subtleties of the topic


Story

In a microservice for image processing, a developer used panic! to handle all exceptional situations. This led to the service crashing on any error instead of returning a proper HTTP response to the client with error details.


Story

In a CLI tool, unwrap() was used for all input-output, not handling possible errors. As a result, on a filesystem error, the program simply terminated without any messages or diagnostics.


Story

In an analytics service, they attempted to use Option for every minor error, losing information about the errors themselves, making debugging more difficult. After switching to Result with enum errors, it became easier to find and fix bugs.