Error handling
Demo: error-handling
In Rust, there are 2 types of error.
| Recoverable | Unrecoverable |
| -------------------------- | ---------------------------- |
| Example: file not found | Example: index out of bounds |
| Handle with Result<T, E> | Handle with panic! |
panic! stop the program immediately and provide feedback.
Result<T, E> enum
Similar to Option<T>, Result<T, E> wraps the value. It provides Ok and Err to make sure the error is catched.
enum Result<T, E> {
Ok(T),
Err(E)
}
It's included in prelude so we don't need to import it explictly.
To handle the error, we can use match.
// fs::read_to_string returns a Result
let result = fs::read_to_string("hello.txt");
let contents = match result {
Ok(contents) => contents,
Err(e) => panic!("There was a problem reading the file: {:?}", e),
};
Propagating errors
Sometimes, we want to propagate the errors from low level to high level, then deal with it. For example, we create a read_file function and call it.
fn read_file(file_name: &str) -> Result<String, io::Error> {
let result = match fs::read_to_string(file_name) {
Ok(string) => string,
Err(error) => return Err(error),
};
Ok(result)
}
fn main() {
let file_string = read_file("src/test.txt");
let contents = match file_string {
Ok(contents) => contents,
Err(e) => panic!("There was a problem reading the file: {:?}", e),
};
println!("{}", contents);
}
We've writen match 2 times. There is a way to prograte it. We don't handle with the error in read_file function, only in the main function.
fn read_file(file_name: &str) -> Result<String, io::Error> {
let result = fs::read_to_string(file_name)?;
Ok(result)
}
Attention: It only works with the function returns a Result.