Rust Error Handling Cheat Sheet
Covers the Result and Option types, the ? operator, custom error types, and idiomatic patterns for propagating and handling errors in Rust.
2 PagesIntermediateApr 15, 2026
Result & Option Basics
The two core types for representing fallible or absent values.
rust
fn divide(a: f64, b: f64) -> Result<f64, String> { if b == 0.0 { Err(String::from("division by zero")) } else { Ok(a / b) }}match divide(10.0, 2.0) { Ok(v) => println!("Result: {}", v), Err(e) => println!("Error: {}", e),}// Option<T> for values that may be absentfn find_first_even(nums: &[i32]) -> Option<i32> { nums.iter().find(|&&n| n % 2 == 0).copied()}if let Some(n) = find_first_even(&[1, 3, 4, 5]) { println!("First even: {}", n);}
The ? Operator
Propagating errors concisely up the call stack.
rust
use std::fs::File;use std::io::{self, Read};fn read_username_from_file() -> Result<String, io::Error> { let mut f = File::open("username.txt")?; // returns early on Err let mut s = String::new(); f.read_to_string(&mut s)?; Ok(s)}// ? also works with Option in functions returning Option<T>fn first_char_upper(s: &str) -> Option<char> { let c = s.chars().next()?; Some(c.to_ascii_uppercase())}
Custom Error Types
Defining a domain-specific error enum with Display and Error impls.
rust
use std::fmt;#[derive(Debug)]enum AppError { NotFound(String), InvalidInput { field: String },}impl fmt::Display for AppError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { AppError::NotFound(what) => write!(f, "not found: {}", what), AppError::InvalidInput { field } => write!(f, "invalid input: {}", field), } }}impl std::error::Error for AppError {}fn lookup(id: u32) -> Result<String, AppError> { if id == 0 { return Err(AppError::NotFound(format!("id {}", id))); } Ok("record".to_string())}
Result/Option Combinators
Common chaining methods for handling values without full match blocks.
- .unwrap()- Returns the Ok/Some value or panics; use only when failure is truly impossible
- .expect("msg")- Like unwrap but with a custom panic message for better diagnostics
- .unwrap_or(default)- Returns the value, or a fallback default if Err/None
- .unwrap_or_else(f)- Returns the value, or computes a fallback from a closure
- .map(f)- Transforms the Ok/Some value, leaving Err/None untouched
- .and_then(f)- Chains a fallible operation that itself returns Result/Option
- .ok()- Converts a Result<T, E> into Option<T>, discarding the error
- .map_err(f)- Transforms the error type/value, leaving Ok untouched
panic! vs Result
When to use unrecoverable panics versus recoverable errors.
- panic!- Unrecoverable error; unwinds (or aborts) the thread — use for bugs/invariants, not expected failures
- Result<T, E>- Recoverable error; forces the caller to explicitly handle or propagate failure
- main() -> Result<(), E>- main can return Result; a returned Err prints Debug output and exits with code 1
- unwrap() in prototypes- Acceptable in examples/tests; replace with proper handling before production
Pro Tip
Use the `thiserror` crate for library error enums (derives Display/Error with minimal boilerplate) and `anyhow::Result` for application code where you just need to propagate errors with context, not match on variants.
Was this cheat sheet helpful?
Explore Topics
#RustErrorHandling#RustErrorHandlingCheatSheet#Programming#Intermediate#ResultOptionBasics#TheOperator#CustomErrorTypes#ResultOptionCombinators#ErrorHandling#CheatSheet#SkillVeris
Advertisement
Sri Hayavadhana Info-Tech
Professional Web Designing Services
- Responsive Websites
- E-commerce Solutions
- SEO Friendly Design
- Fast & Secure
- Support & Maintenance