Module 6 • Lesson 32

The ? Operator

📚 8 min💻 Free🦀 nixus.pro

The ? Operator: Ergonomic Error Propagation

The ? operator is syntactic sugar for early return on error. It is the most ergonomic way to handle errors in Rust.

use std::fs;
use std::num::ParseIntError;
use std::io;

// Without ?: verbose
fn read_and_parse_verbose(path: &str) -> Result {
    let content = match fs::read_to_string(path) {
        Ok(s) => s,
        Err(e) => return Err(e),
    };
    // But we can not parse here without error type mismatch...
    Ok(42)
}

// With ?: clean and readable
fn read_and_parse(path: &str) -> Result> {
    let content = fs::read_to_string(path)?; // Returns Err if file read fails
    let n: i32 = content.trim().parse()?;     // Returns Err if parse fails
    Ok(n * 2)
}

// ? also works with Option
fn first_even(v: &[i32]) -> Option {
    let first = v.first()?;     // Returns None if empty
    if first % 2 == 0 { Some(*first) } else { None }
}

// ? works in main() too (requires main to return Result)
fn main() -> Result<(), Box> {
    // let n = read_and_parse("numbers.txt")?;
    println!("Success!");
    Ok(())  // main returns Ok(())
}

The From Trait and Error Conversion

use std::num::ParseIntError;
use std::io;

#[derive(Debug)]
enum AppError {
    Io(io::Error),
    Parse(ParseIntError),
}

impl From for AppError {
    fn from(e: io::Error) -> Self { AppError::Io(e) }
}

impl From for AppError {
    fn from(e: ParseIntError) -> Self { AppError::Parse(e) }
}

// Now ? auto-converts these errors!
fn process_file(path: &str) -> Result {
    let content = std::fs::read_to_string(path)?; // io::Error -> AppError via From
    let n: i32 = content.trim().parse()?;          // ParseIntError -> AppError via From
    Ok(n)
}

🎯 Practice

  1. Write a function that reads a CSV file and returns Vec<Vec<String>>, using ? throughout
  2. Create an AppError enum and impl From for two different error types
  3. Write fn main() -> Result<(), Box<dyn Error>> that reads a file and parses JSON-ish data

🎉 Key Takeaways