🎓 A1Learner
🔍

Rust Main Returns Result

A main that returns a Result reports the program's success or failure to the operating system. A main returning Result can use ? anywhere inside it.

The long way: match inside a plain main

A plain main cannot use ?, so a fallible call needs a match:

fn main() {
    let n: Result<i32, std::num::ParseIntError> = "21".parse();
    match n {
        Ok(v) => println!("answer = {}", v * 2),
        Err(e) => println!("failed: {e}"),
    }
}

main can return a Result

Change main's return type, use ? inside it, and end with Ok(()). A program that ends this way exits with code 0.

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let n: i32 = "21".parse()?;
    println!("answer = {}", n * 2);
    Ok(())
}

One box holds any error

Box<dyn Error> is the error type that accepts them all, so different ? calls in one function may fail in different ways.

use std::error::Error;
fn doubled(text: &str) -> Result<i32, Box<dyn Error>> {
    let n: i32 = text.trim().parse()?;
    Ok(n * 2)
}

Failure leaves through main

Feed main bad text and the parse error travels out of main. Rust prints it after Error:, and the program exits with a non-zero code.

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let n: i32 = "abc".parse()?;
    println!("n = {n}");
    Ok(())
}

Example

use std::error::Error;
fn doubled(text: &str) -> Result<i32, Box<dyn Error>> {
    let n: i32 = text.trim().parse()?;
    Ok(n * 2)
}
fn main() -> Result<(), Box<dyn Error>> {
    let answer = doubled("21")?;
    println!("answer = {}", answer);
    Ok(())
}

Key points

  • Return std::process::ExitCode from main when the exact number matters.
  • ExitCode replaces a Result return in that case.
  • The number 2 for wrong usage is one example.

In this example, doubled parses the text "21" into a number and doubles it. The parse could fail. So doubled returns a Result. Its error type is Box<dyn Error>. That is a box that can hold any kind of error. main also returns Result<(), Box<dyn Error>>, so it can use ? on doubled: success gives the answer 42, which main prints before returning Ok(()). If the text had been "abc", the parse error would travel out of main. Rust would print it after the word Error:. The program would exit with a non-zero code.

Note

Small programs and command-line tools love this pattern: ? everywhere in main, no unwrap, and a clean error report when something goes wrong.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Rust Playground

Exercise

What happens when main returns an Err value?