Summary - Error handling
- Rust course
- Beginner
- Lesson 111/115
- 5 min
Combine Result, ? and match to build a number-reading function.
Error handling summary
Expected errors are returned with Result<T, E>; bugs stop the program with panic!. ? propagates the error upward and converts it with From. To handle it on the spot, use match, if let, unwrap_or and map_err. Use unwrap/expect only where failure is impossible. Defining your own error enum for application-specific errors is a good habit.
Your own error type
Define an enum for application-specific errors; each variant is a reason for failure:
#[derive(Debug)]
enum HesapHatasi {
Bos,
Gecersiz(String),
}
fn ortalama(s: &str) -> Result<f64, HesapHatasi> {
if s.trim().is_empty() {
return Err(HesapHatasi::Bos);
}
// parse each piece, turn the error into Gecersiz with map_err
todo!()
}In later lessons you'll implement Display and std::error::Error for this type and combine it with other errors via ?.
Practice Average calculation
Complete the function fn ortalama(s: &str) -> Result<f64, HesapHatasi> with the HesapHatasi enum above: Bos for empty text; trim each comma-separated piece and convert it to f64, returning Gecersiz(piece) on error (map_err and ?). Print the results for "2,4,9", "" and "1,x" with {:?}, separated by spaces.
Starter code
#[derive(Debug)]
enum HesapHatasi {
Bos,
Gecersiz(String),
}
fn main() {
// buraya yaz
}Sample solution
#[derive(Debug)]
enum HesapHatasi {
Bos,
Gecersiz(String),
}
fn ortalama(s: &str) -> Result<f64, HesapHatasi> {
if s.trim().is_empty() {
return Err(HesapHatasi::Bos);
}
let mut toplam = 0.0;
let mut adet = 0;
for p in s.split(',') {
let p = p.trim();
let n: f64 = p.parse().map_err(|_| HesapHatasi::Gecersiz(p.to_string()))?;
toplam += n;
adet += 1;
}
Ok(toplam / adet as f64)
}
fn main() {
println!("{:?} {:?} {:?}", ortalama("2,4,9"), ortalama(""), ortalama("1,x"));
}Expected output
Ok(5.0) Err(Bos) Err(Gecersiz("x"))
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What is the advantage of your own error enum over String errors?
- It always uses less memory
- It doesn't panic
- The compiler requires it
- The caller can behave differently by error kind with match Correct answer
Explanation: A String can only be read; an enum lets the program decide (e.g. a default for Bos, a warning for Gecersiz).
2 Convert and propagate
let n: f64 = p.parse().map_err(|_| HesapHatasi::Gecersiz(p.to_string()))____;
let n: f64 = p.parse().map_err(|_| HesapHatasi::Gecersiz(p.to_string()))?;
Explanation: map_err converts the error into your own type and ? returns it to the caller.
3 Group summary
| Term | Meaning |
|---|---|
Result<T, E> |
Expected error |
panic! |
Bug |
? |
Error propagation |
enum HesapHatasi |
Custom error type |