Error Handling

  • recoverable error such as file not found, use Result<T, E>

  • unrecoverable error such as accessing a location beyond the end of array, use panic!

  • you can switch from unwinding to aborting upon a panic by adding panic = 'abort' to the appropriate [profile] sections in your Cargo.toml file

    [profile.release]
    panic = 'abort'
    

Result type


#![allow(unused)]
fn main() {
enum Result<T, E> {
    Ok(T),
    Err(E),
}
}

Instead of unwrap, expect should be used to give more context about the operation


#![allow(unused)]
fn main() {
let file = std::fs::File::open("hello.txt")
           .expect("hello.txt should be included in the project")
}

? operator can be used with Result or Option type, but can't mix can match between them


#![allow(unused)]
fn main() {
// e? expression, where e is of type Result<T, E>,  equals to
match e {
  Ok(x) => x,
  Err(err) => { return Err(err); }
}
}

Sample Code

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

//  using panic!
fn read_file(path: &str) -> io::Result<()> {
    let mut file = match File::open(path) {
        Ok(file) => file,
        Err(error) => panic!("Error: {:?}", error),
    };
    let mut buf = String::new();
    file.read_to_string(&mut buf)?;
    println!("{:?}", buf);
    Ok(())
}

// using panic!
fn read_or_create_file(path: &str) -> io::Result<()> {
    let mut file = File::open(path).unwrap_or_else(|error|{
       if error.kind() == ErrorKind::NotFound {
            File::create(path).unwrap_or_else(|error| {
                panic!("Error creating file {:?}", error);
            })
        } else {
            panic!("Error opening file");
        }
    });
    let mut buf = String::new();
    file.read_to_string(&mut buf)?;
    println!("{:?}", buf);
    Ok(())
}

// using Result propagation operator ?
fn read_content(path: &str) -> io::Result<String> {
    let mut buf = String::new();
    let mut f = File::open(path)?;
    File::read_to_string(&mut f,&mut buf)?;
    Ok(buf)
}

fn main() -> io::Result<()> {
    read_file("hello.txt")?;
    read_or_create_file("abc.txt")?;
    println!("{:?}", read_content("hello.txt")?);
    Ok(())
}