typestar

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

  1. Implementing Error requires Debug and Display.
  2. source returns the error underneath this one.
  3. Callers can then walk the whole chain of causes.

Keywords and builtins used here

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.

Type this snippet

Step 2 of 5 in Your own error types, step 9 of 15 in Error handling.

← Previous Next →