9.2. Recoverable Errors with Result

One can use unwrap to simplify boilerplate code that match incurs, but it only emits builtin panic messages; If one needs custom messages, use expect .

use std::fs::File;

fn main() {
		// let f = File::open("hello.txt").unwrap();
    let f = File::open("hello.txt").expect("Failed to open hello.txt");
}

A Shortcut for Propagating Errors: the ? Operator

? will act like unwrap when the Result is Ok , and it will return from current function stack with transformed error when the Result is Err .

Error values that have the ? operator called on them go through the from function, defined in the From trait in the standard library, which is used to convert errors from one type into another. In below example, if File::open returns Err of A type, the from function in the impl From<A> for io::Error trait definition will be called to transform A to io::Error for read_username_from_file to return.

use std::fs::File;
use std::io;
use std::io::Read;

fn read_username_from_file() -> Result<String, io::Error> {
    let mut s = String::new();

    File::open("hello.txt")?.read_to_string(&mut s)?;

    Ok(s)
}

? can also be used for functions returning Option in a similar way.