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.

Create a free account to save this page, take notes and track your progress. Sign in

Result

Functions that can fail return Result<T, E>: Ok(value) or Err(error). The caller must deal with the error.

Returning Result
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:

Propagating with ?
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: 0

Run this on your computer — see “Get Started” for setup.

Test yourself

What does the ? operator do on an Err value?

  1. Panics
  2. Returns the error from the current function
  3. Ignores it
  4. Converts it to None
Show answer

Answer: Returns the error from the current function

Was this page helpful?