Summary - Advanced error handling
- Rust course
- Intermediate
- Lesson 70/115
- 5 min
Combine thiserror and From to build a config reader error.
Advanced error handling summary
Error types implement Debug + Display + Error. Libraries use concrete enums (thiserror), applications a flexible type (anyhow or Box<dyn Error>). impl From enables automatic conversion with ?. Context (with_context or map_err) makes errors understandable. source() gives the underlying cause of an error and can be walked as a chain.
The error chain
An error type implementing source can give a high-level message without losing the cause:
#[derive(Debug)]
struct UstHata {
kaynak: ParseIntError,
}
impl fmt::Display for UstHata {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "yapılandırma yüklenemedi")
}
}
impl Error for UstHata {
fn source(&self) -> Option<&(dyn Error + 'static)> {
Some(&self.kaynak)
}
}The chain is walked with while let Some(k) = s { ..; s = k.source(); }.
Practice Print the chain
Write the UstHata type above. Create an instance with "x".parse::<i32>().unwrap_err(); print the error first, then walk the source chain as neden: MESSAGE.
Starter code
use std::error::Error;
use std::fmt;
use std::num::ParseIntError;
fn main() {
// buraya yaz
}Sample solution
use std::error::Error;
use std::fmt;
use std::num::ParseIntError;
#[derive(Debug)]
struct UstHata {
kaynak: ParseIntError,
}
impl fmt::Display for UstHata {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "yapılandırma yüklenemedi")
}
}
impl Error for UstHata {
fn source(&self) -> Option<&(dyn Error + 'static)> {
Some(&self.kaynak)
}
}
fn main() {
let e = UstHata { kaynak: "x".parse::<i32>().unwrap_err() };
println!("{}", e);
let mut s = e.source();
while let Some(k) = s {
println!(" neden: {}", k);
s = k.source();
}
}Expected output
yapılandırma yüklenemedi neden: invalid digit found in string
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What does <code>Error::source</code> return by default?
- The Display message
- It panics
- None Correct answer
- The error itself
Explanation: Error types with an underlying cause override source to return Some(&inner_error).
2 Give the cause
impl Error for UstHata {
fn ____(&self) -> Option<&(dyn Error + 'static)> {
Some(&self.kaynak)
}
}
impl Error for UstHata {
fn source(&self) -> Option<&(dyn Error + 'static)> {
Some(&self.kaynak)
}
}
Explanation: source returns the underlying error.
3 Group summary
| Term | Meaning |
|---|---|
impl Error |
Error contract |
impl From<E> |
Conversion with ? |
with_context |
Adds context |
source() |
Underlying cause |