Crash Courses · Masters
Error Handling with Result & Option
Propagate errors without exceptions using the ? operator
35 min read+180 XP on completionCert: Rust Crash Course
Tap any word in the text below to start reading from there.
Error Handling with Result & Option
Result<T, E>
use std::num::ParseIntError;
fn parse_age(s: &str) -> Result<u32, ParseIntError> {
let n = s.trim().parse::<u32>()?; // ? propagates the error
Ok(n)
}
fn main() {
match parse_age("25") {
Ok(age) => println!("Age: {}", age),
Err(e) => println!("Parse error: {}", e),
}
match parse_age("abc") {
Ok(age) => println!("Age: {}", age),
Err(e) => println!("Parse error: {}", e),
}
}The ? Operator
? is shorthand for:
// This:
let n = s.parse::<u32>()?;
// Expands to roughly:
let n = match s.parse::<u32>() {
Ok(v) => v,
Err(e) => return Err(e.into()),
};Chaining Operations
use std::fs;
fn read_username() -> Result<String, std::io::Error> {
let content = fs::read_to_string("username.txt")?; // ? here
Ok(content.trim().to_string())
}Option Combinators
let s = "hello world";
let upper: Option<String> = s.split_whitespace()
.next() // Option<&str>
.map(str::to_uppercase); // Option<String>
println!("{:?}", upper); // Some("HELLO")
// unwrap_or provides a default
let word = s.split_whitespace().next().unwrap_or("default");Custom Error Types
use std::fmt;
#[derive(Debug)]
enum AppError {
ParseError(String),
NotFound(String),
}
impl fmt::Display for AppError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AppError::ParseError(msg) => write!(f, "Parse error: {}", msg),
AppError::NotFound(key) => write!(f, "Not found: {}", key),
}
}
}
impl std::error::Error for AppError {}
fn find_user(id: u32) -> Result<String, AppError> {
if id == 1 { Ok("Jordan".into()) }
else { Err(AppError::NotFound(format!("id={}", id))) }
}The anyhow Crate
For application code (not libraries), anyhow eliminates boilerplate:
// Cargo.toml: anyhow = "1"
use anyhow::{Result, Context};
fn run() -> Result<()> {
let n: u32 = "42".parse().context("failed to parse config")?;
println!("{}", n);
Ok(())
}Reading progress
0% read
In this module
Result<T, E>
? operator
unwrap()
expect(msg)
0%