Result and ? operator for clean error propagation

Marcus Chen Jan 2026
1 tab
use std::fs;
use std::num::ParseIntError;

fn read_port(path: &str) -> Result<u16, Box<dyn std::error::Error>> {
    let contents = fs::read_to_string(path)?;
    let port: u16 = contents.trim().parse()?;
    Ok(port)
}
1 file · rust Explain with highlit

Rust's Result<T, E> forces you to handle errors explicitly, but the ? operator makes it ergonomic. When a function returns Result, using ? automatically returns early with the error if it's Err, or unwraps the value if it's Ok. This replaces verbose match or unwrap() chains. The key is that ? only works in functions that return Result or Option, which keeps error handling explicit at boundaries. I use this everywhere: file I/O, parsing, network calls. It reads sequentially like exceptions but without hidden control flow. The compiler ensures you can't ignore errors, and the calling code decides how to handle them. This is one of Rust's killer features for reliability.