Implementing std::error::Error in Rust
The Error trait is what lets your type travel as a boxed error and report a cause.
use std::error::Error;
use std::fmt;
#[derive(Debug)]
struct ParseFailure {
line: usize,
cause: std::num::ParseIntError,
}
impl fmt::Display for ParseFailure {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "line {} is not a number", self.line)
}
}
impl Error for ParseFailure {
fn source(&self) -> Option<&(dyn Error + 'static)> {
Some(&self.cause)
}
}
fn main() {
let cause = "x".parse::<i32>().unwrap_err();
let err = ParseFailure { line: 12, cause };
println!("{err}");
if let Some(inner) = err.source() {
println!("caused by: {inner}");
}
}
How it works
- Implementing
ErrorrequiresDebugandDisplay. sourcereturns the error underneath this one.- Callers can then walk the whole chain of causes.
Keywords and builtins used here
OptionParseFailureResultSomedynfmtfnfori32ifimplletmainmutselfsourcestaticstdstructuseusize
The run, in numbers
- Lines
- 29
- Characters to type
- 567
- Tokens
- 170
- Three-star pace
- 105 tpm
At the three-star pace of 105 tokens a minute, this run takes about 97 seconds.
Step 2 of 5 in Your own error types, step 9 of 15 in Error handling.