Amos
Amos

Reputation: 3276

How to implement an error wrapper for all existing Errors?

I want to use my customised error type in all functions and I need to wrap the existing standard errors so that the ? operator will succeed.

Here is what I am doing:

use std::{error::Error, fmt, fs};

#[derive(Debug)]
enum MyError {
    A,
    B,
}

impl fmt::Display for MyError {
    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
        Ok(())
    }
}

impl Error for MyError {
    fn description(&self) -> &str {
        ""
    }
}

trait NotMyError {}

impl<T: NotMyError + Error> From<T> for MyError {
    fn from(_: T) -> MyError {
        MyError::A
    }
}

fn test() -> Result<(), MyError> {
    fs::read_dir("test")?;
    Ok(())
}

fn main() {}

The compiler complains:

error[E0277]: the trait bound `std::io::Error: NotMyError` is not satisfied
  --> src/main.rs:30:5
   |
30 |     fs::read_dir("test")?;
   |     ^^^^^^^^^^^^^^^^^^^^^ the trait `NotMyError` is not implemented for `std::io::Error`
   |
   = note: required because of the requirements on the impl of `std::convert::From<std::io::Error>` for `MyError`
   = note: required by `std::convert::From::from`

Upvotes: 25

Views: 11838

Answers (1)

Kornel
Kornel

Reputation: 100220

There's an excellent post about it. To get first-class support for your error you need to do two things:

  • Implement the Error trait for your type.
  • Implement std::convert::From for error types you want to use seamlessly with the ? operator (the quick_error crate helps automate this).

Upvotes: 25

Related Questions