Rust’s error handling is elegant and type-safe. Here’s how to use it effectively.
Option Type
fn find_user(id: u32) -> Option<String> {
if id > 0 {
Some(format!("User {}", id))
} else {
None
}
}
match find_user(1) {
Some(name) => println!("Found: {}", name),
None => println!("Not found"),
}
Result Type
use std::fs::File;
fn read_file(path: &str) -> Result<String, std::io::Error> {
std::fs::read_to_string(path)
}
match read_file("data.txt") {
Ok(content) => println!("Content: {}", content),
Err(e) => println!("Error: {}", e),
}
Error Propagation
fn read_config() -> Result<String, std::io::Error> {
let content = std::fs::read_to_string("config.txt")?;
Ok(content)
}
Custom Errors
use std::fmt;
#[derive(Debug)]
struct CustomError {
message: String,
}
impl fmt::Display for CustomError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.message)
}
}
Best Practices
- Use
Resultfor recoverable errors - Use
Optionfor optional values - Propagate errors with
? - Create custom errors when needed
- Handle errors explicitly
Conclusion
Handle errors elegantly in Rust! 🦀