Skip to main content
Error handling with the Result type. Result is the type used for returning and propagating errors. It is an enum with the variants, Ok(T), representing success and containing a value, and Err(E), representing error and containing an error value.
enum Result {
   Ok: T,
   Err: E,
}
Functions return Result whenever errors are expected and recoverable. A simple function returning Result might be defined and used like so:
fn parse_version(header: felt252) -> Result {
    match header {
        0 => Ok(0),
        1 => Ok(1),
        _ => Err('invalid version'),
    }
}

let version = parse_version(1);
match version {
    Ok(v) => println!("working with version {}", v),
    Err(e) => println!("error parsing version: {:?}", e)
}

Results must be used

A common problem with using return values to indicate errors is that it is easy to ignore the return value, thus failing to handle the error. Result is annotated with the #[must_use] attribute, which will cause the compiler to issue a warning when a Result value is ignored.

Method overview

In addition to working with pattern matching, Result provides a wide variety of different methods.

Querying the variant

The is_ok and is_err methods return true if the Result is Ok or Err, respectively.

Extracting contained values

These methods extract the contained value in a Result when it is the Ok variant. If the Result is Err:
  • expect panics with a provided felt252 error message
  • unwrap panics with a generic message
  • unwrap_or returns the provided default value
  • unwrap_or_default returns the default value of the type T (which must implement the Default trait)
  • unwrap_or_else returns the result of evaluating the provided function
These methods extract the contained value in a Result when it is the Err variant. If the Result is Ok:
  • expect_err panics with a provided felt252 error message
  • unwrap_err panics with a generic message

Transforming contained values

These methods transform Result to Option:
  • ok transforms Result into Option, mapping Ok(v) to Some(v) and Err(e) to None
  • err transforms Result into Option, mapping Ok(v) to None and Err(e) to Some(e)
This method transforms the contained value of the Ok variant:
  • map transforms Result into Result by applying the provided function to the contained value of Ok and leaving Err values unchanged
This method transforms the contained value of the Err variant:
  • map_err transforms Result into Result by applying the provided function to the contained value of Err and leaving Ok values unchanged
These methods transform a Result into a value of a possibly different type U:
  • map_or applies the provided function to the contained value of Ok, or returns the provided default value if the Result is Err
  • map_or_else applies the provided function to the contained value of Ok, or applies the provided default fallback function to the contained value of Err

Boolean operators

These methods treat the Result as a boolean value, where Ok acts like true and Err acts like false. There are two categories of these methods: ones that take a Result as input, and ones that take a function as input. The and and or methods take another Result as input, and produce a Result as output. The and method can produce a Result value having a different inner type U than Result. The or method can produce a Result value having a different error type F than Result.
methodselfinputoutput
andErr(e)(ignored)Err(e)
andOk(x)Err(d)Err(d)
andOk(x)Ok(y)Ok(y)
orErr(e)Err(d)Err(d)
orErr(e)Ok(y)Ok(y)
orOk(x)(ignored)Ok(x)
The and_then and or_else methods take a function as input, and only evaluate the function when they need to produce a new value. The and_then method can produce a Result value having a different inner type U than Result. The or_else method can produce a Result value having a different error type F than Result.
methodselffunction inputfunction resultoutput
and_thenErr(e)(not provided)(not evaluated)Err(e)
and_thenOk(x)xErr(d)Err(d)
and_thenOk(x)xOk(y)Ok(y)
or_elseErr(e)eErr(d)Err(d)
or_elseErr(e)eOk(y)Ok(y)
or_elseOk(x)(not provided)(not evaluated)Ok(x)

The question mark operator, ?

When writing code that calls many functions that return the Result type, handling Ok/Err can be tedious. The question mark operator, ?, hides some of the boilerplate of propagating errors up the call stack. It replaces this:
use core::integer::u8_overflowing_add;

fn add_three_numbers(a: u8, b: u8, c: u8) -> Result {
    match u8_overflowing_add(a, b) {
        Ok(sum_ab) => {
            match u8_overflowing_add(sum_ab, c) {
                Ok(total) => Ok(total),
                Err(e) => Err(e),
            }
        },
        Err(e) => Err(e),
    }
}
With this:
use core::integer::u8_overflowing_add;

fn add_three_numbers_2(a: u8, b: u8, c: u8) -> Result {
    let total = u8_overflowing_add(u8_overflowing_add(a, b)?, c)?;
    Ok(total)
}
It’s much nicer!

Iterating over Result

A Result can be iterated over. This can be helpful if you need an iterator that is conditionally empty. The iterator will either produce a single value (when the Result is Ok), or produce no values (when the Result is Err). For example, into_iter contains Some(v) if the Result is Ok(v), and None if the Result is Err.

Enums

ResultThe type used for returning and propagating errors. It is an enum with the variants Ok: T , representing success and containing a value, and Err: E , representing error and containing an…

Traits

ResultTrait
I