Should the names of variants in a custom Error enum append the word Error, or it sufficient to have the word Error in the name of the enum itself?
For example, rather than MyError::IOError, I would prefer MyError::IO for the sake of brevity:
pub enum MyError {
IO,
ParseJSON,
// ...
}
I can think of two concerns.
If someone does a splat-import of all the enum variants via use mylib::MyError::* then a name like IO on its own will no longer connote "I'm an error type". But I think that's fine because rather than a splat-import I would ordinarily expect use mylib or use mylib::MyError; and if the library user really wants the bare enum variants they can do something like use mylib::MyError::IO as MyLibIOError.
The behavior of #[derive(Debug)] for an enum is to present the bare name of the enum variant, which is problematic a type like MyError::IO because it loses the MyError:: context. The solution is for the Error type to avoid #[derive(Debug)] and instead provide an implementation of Debug which includes the name of the enum. (Playground)
As I learn how to design Rust library error APIs, I'm trying to understand all the options and all the implications. I don't mind writing extra boilerplate in my library's error type code if it makes the experience better for users.
The naming of error enum variants is a minor concern, but at least if nobody points out significant flaws in my approach, I can file it away as "solved" and move onto other dimensions (like the pros and cons of error enums vs. error-kind enums.)
Personally, I would prefer the bare version, without the Error suffix, which goes against the benefits of scoping, as you mentioned.
The debug format is IMO not a big concern, since most of the time the context indicates that it is an error that is being printed. Moreover, the Debug representation is not designed to be user-facing, and we can add the detailed explanation in Display.
In the end, it's opinion-based, so just pick whatever you like