Use Result<T, E> for recoverable errors and panic! only for unrecoverable ones.
use std::fs::File;
use std::io::ErrorKind;
fn read_file(path: &str) -> Result<String, std::io::Error> {
let mut file = File::open(path)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
Ok(contents)
}
fn main() {
match read_file("hello.txt") {
Ok(content) => println!("{content}"),
Err(e) if e.kind() == ErrorKind::NotFound => println!("File not found"),
Err(e) => panic!("Unexpected error: {e}"),
}
}
The ? operator propagates errors automatically, while match lets you handle specific cases like NotFound before panicking on unexpected failures.