Result and the ? Operator β Rust Error Handling Patterns
Handling errors as types without try-catch
Java/Python catch errors with try-catch. The problem: you can't tell from a function signature what exceptions it might throw. Rust puts errors inside the type system.
Result<T, E> β T is the success value, E the error. Looking at the signature tells you whether the function can fail and what error it returns.
fn read_file(path: &str) -> Result<String, io::Error> {
let content = fs::read_to_string(path)?;
Ok(content)
}
? is the key. On Err, return immediately; on Ok, extract the inner value. More concise than try-catch with explicit error propagation paths.
unwrap() panics (crashes) on error. Convenient for prototyping but forbidden in production.
Key Points
Fallible functions return Result<T, E>
? operator auto-propagates errors to the caller
Transform/handle errors with match or map_err
Define custom error types with thiserror/anyhow crates
Pros
- ✓ Error possibility visible from function signature alone
- ✓ Error propagation is concise with ? operator
Cons
- ✗ Error type conversion (From trait) is tedious at first
- ✗ Temptation to overuse unwrap is strong