Lesson 14 / 25
Result and the ? Operator
Errors in the type signature.
Ok, Err and early return
Functions that can fail return Result<T, E>: Ok(value) or Err(error). The ? operator unwraps an Ok value or returns the error from the current function immediately, keeping the happy path readable. Callers then match on the result or propagate it further. Because errors are part of the type, the compiler warns if you ignore a Result.
Recoverable versus unrecoverable
Result and ? propagate recoverable errors; panics stop on bugs.
Parsing with ? and handling the error, run
I ran this with Rust 1.99.0 (cargo run, edition 2024, standard library only). Adding "3" and " 4 " gives Ok(7). "four" fails to parse, and ? returns the ParseIntError immediately. The match prints the error's message for the negative number, which is not a valid u32.
use std::num::ParseIntError;
fn parse_qty(s: &str) -> Result<u32, ParseIntError> {
s.trim().parse::<u32>()
}
fn total(a: &str, b: &str) -> Result<u32, ParseIntError> {
let x = parse_qty(a)?; // ? returns the error early
let y = parse_qty(b)?;
Ok(x + y)
}
fn main() {
println!("{:?}", total("3", " 4 "));
println!("{:?}", total("3", "four"));
match total("10", "-1") {
Ok(n) => println!("ok {n}"),
Err(e) => println!("could not add: {e}"),
}
}
Output:
Ok(7)
Err(ParseIntError { kind: InvalidDigit })
could not add: invalid digit found in stringUse ? liberally
Propagate errors with ? and handle them at a boundary (main, a request handler) where you can report or recover.
Quick check: What does the ? operator do on an Err value?
- Converts it to None silently
- Panics
- Ignores the error
- Returns the error from the current function
Answer
Returns the error from the current function — Early return keeps code flat.