Custom errors and implementing the Error trait

Here is a working example that demonstrates options for error handling in functions that can be return multiple error types. My custom error type implements the Error trait, but does so without defining any of its methods. Why does this work?

https://github.com/mvolkmann/rust-error-handling/blob/main/src/main.rs#L18

It is because they all provide default implementations.

What do you mean by "they". It would seem in this case that all the compiler can see is that GetDogsError is an enum. Is it able to determine that all the variants of this enum wrap a type the implements the Error trait? Would having a variant that doesn't do this break it?

By "they" I mean all the functions defined on the trait. And the default impls are far from that clever. They certainly do not look inside your enum.

The default impls are:

pub trait Error: Debug + Display {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        None
    }

    fn description(&self) -> &str {
        "description() is deprecated; use Display"
    }

    fn cause(&self) -> Option<&dyn Error> {
        self.source()
    }
}
2 Likes

Based on that would you say it's generally a bad idea for custom error types to just write this?

impl Error for GetDogsError {}

For enum errors that just wrap other errors, I would probably implement source, but the others should typically not be implemented. The error messages and such should be displayed through the Debug or Display traits.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.