Rust groups errors into two major categories: recoverable and unrecoverable errors, and Rust does not treat them the same by handling exceptions like other languages.

For recoverable errors, it will has the type Result<T, E> and for unrecoverable errors, the panic! macro will stops execution.

Unrecoverable Errors with panic!

There are two ways to cause a panic in practice: by taking an action that causes the code to panic(i.e. access out of bound) or by explicitly calling the panic! macro.

Recoverable Errors with Result

use std::fs::File;
use std::io::ErrorKind;

fn main() {
    let greeting_file_result = File::open("hello.txt");

    let greeting_file = match greeting_file_result {
        Ok(file) => file,
        Err(error) => match error.kind() {
            ErrorKind::NotFound => match File::create("hello.txt") {
                Ok(fc) => fc,
                Err(e) => panic!("Problem creating the file: {:?}", e),
            },
            other_error => {
                panic!("Problem opening the file: {:?}", other_error);
            }
        },
    };
}

Shortcuts also exists for panic on error:

Similarly, if we want to propagate the error, ? could be used

use std::fs::File;
use std::io::{self, Read};

fn read_username_from_file() -> Result<String, io::Error> {
    let mut username_file = File::open("hello.txt")?;
    let mut username = String::new();
    username_file.read_to_string(&mut username)?;
    Ok(username)
}

The ? placed after a Result value is defined to work like this: If the value of the Result is an Ok, the value inside the Ok will get returned from this expression, and the program will continue. If the value is an Err, the Err will be returned from the whole function.

Notice that the ? operator can only be used inside a function that returns Result or Option