15.4 Error Propagation with the ? Operator

15.4.1 Mechanism of the ? Operator

The ? operator simplifies error handling by propagating errors up the call stack.

  • On Ok Variant: Unwraps the value and continues execution.
  • On Err Variant: Returns the error from the current function immediately.

Example Using ?:

#![allow(unused)]
fn main() {
use std::fs::File;
use std::io::{self, Read};
fn read_username_from_file() -> Result<String, io::Error> {
    let mut s = String::new();
    File::open("username.txt")?.read_to_string(&mut s)?;
    Ok(s)
}
}

Before the ? operator was introduced, error handling often involved using match statements to handle Result types.

Example Without ? (Using match):

#![allow(unused)]
fn main() {
use std::fs::File;
use std::io::{self, Read};
fn read_username_from_file() -> Result<String, io::Error> {
    let mut s = String::new();
    let mut file = match File::open("username.txt") {
        Ok(file) => file,
        Err(e) => return Err(e),
    };
    match file.read_to_string(&mut s) {
        Ok(_) => Ok(s),
        Err(e) => Err(e),
    }
}
}