Error Handling

Sources:
https://blog.burntsushi.net/rust-error-handling/
https://doc.rust-lang.org/rust-by-example/error.html

Use ?

Source: https://cheats.rs/#idiomatic-rust

Your code will be much more readable and concise with ?.

Don't write:

#[allow(unused)]
fn main() -> std::io::Result<()> {
    let f = std::fs::File::open("hello.txt");

    let f = match f {
        Ok(file) => file,
        Err(e) => return Err(e),
    };

    Ok(())
}

Do write:

#[allow(unused)]
fn main() -> std::io::Result<()> {
    let f = std::fs::File::open("hello.txt")?;

    Ok(())
}

Error Trait Object

Source: https://doc.rust-lang.org/rust-by-example/error/multiple_error_types/boxing_errors.html

Sometimes (but not always) it is useful to use the Error trait object to propagate original errors.

Do write:

#[allow(unused)]
fn error_propagation() -> Result<(), Box<dyn std::error::Error>> {
    let f = std::fs::File::open("hello.txt")?;

    Ok(())
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    error_propagation()
}

Use type to Create a (Shorter) Result Alias

Source: https://doc.rust-lang.org/rust-by-example/error/result/result_alias.html

type allows you to create a type alias. You can use it to make your Result type more concise.

#![allow(unused)]
fn main() {
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
}

Use map(), map_or(), and(), and_then(), unwrap(), unwrap_or(), Etc.

Sources:
https://doc.rust-lang.org/rust-by-example/error/result.html
https://doc.rust-lang.org/rust-by-example/error/option_unwrap.html

Both Result and Option provide many helper methods to process them in various ways. You can use them instead of match. For example, map() for Option maps Some to Some by applying the provided lambda function, and None to None.

The following is an example of using match to process Option.

fn main() {
    let opt = Some(1);

    match opt {
        Some(i) => println!("{}", i),
        None => (),
    }
}

The same can be done with map().

fn main() {
    let opt = Some(1);

    opt.map(|i| println!("{}", i));
}

There are other convenient functions like map_or(), map_or_else(), and(), and_then(), unwrap(), unwrap_or(), etc. for both Result and Option.