Rust Tutorial · Error Handling · Lesson 18 of 29
Rust Result and the ? Operator
Return recoverable errors with Result, propagate them with ?, and handle them with match and combinators.
Result
Functions that can fail return Result<T, E>: Ok(value) or Err(error). The caller must deal with the error.
fn parse_quantity(input: &str) -> Result<u32, String> {
let n: u32 = input.trim().parse().map_err(|_| format!("'{input}' is not a number"))?;
if n == 0 || n > 10 {
return Err(format!("quantity {n} must be between 1 and 10"));
}
Ok(n)
}
fn main() {
for input in ["3", "abc", "50"] {
match parse_quantity(input) {
Ok(q) => println!("ok: {q}"),
Err(e) => println!("error: {e}"),
}
}
}
Output
ok: 3 error: 'abc' is not a number error: quantity 50 must be between 1 and 10
Run this on your computer — see “Get Started” for setup.
The ? operator
? returns early with the error if there is one, and unwraps the value otherwise, so error propagation is a
single character:
use std::num::ParseIntError;
fn total(a: &str, b: &str) -> Result<i64, ParseIntError> {
let x: i64 = a.parse()?; // returns the error early if parsing fails
let y: i64 = b.parse()?;
Ok(x + y)
}
fn main() {
println!("{:?}", total("40", "2"));
println!("{:?}", total("40", "two"));
let fallback = total("x", "1").unwrap_or(0);
println!("with fallback: {fallback}");
}
Output
Ok(42)
Err(ParseIntError { kind: InvalidDigit })
with fallback: 0Run this on your computer — see “Get Started” for setup.
Test yourself
What does the ? operator do on an Err value?
PanicsReturns the error from the current functionIgnores itConverts it to None
Show answer
Answer: Returns the error from the current function