I have been looking at adopting error-chain to reduce error code boilerplate in my projects.
When defining a new custom error in error-chain, fully 50% of the work is defining a description field. As it always seems to be similar (but not usually identical) to the Display trait implementation, I began to wonder why there were two ways to "display" an error, and whether it would be possible to implement them in a DRY manner (at least for common use cases).
I could find no documentation to clarify this situation for me. Can this be documented in some way so as to provide context to new Rust users on which way to turn when arriving at the Error fork on the road to Rust proficiency?
I have come to understand that .description() could be considered somewhat vestigial at this point. If true, I wonder whether it makes sense to establish a convention for defining .description(), such that it is can be deprecated, thus avoiding further confusion?
I am not an expert in Rust, but in the interest of clarity, here is one way we might go about removing description from the list of things the user has to think about, without breaking backward compat. The goal is to make description something that all users can simply ignore in the future, further reducing the amount of boilerplate associated with best-practices error handling in Rust.
We begin establishing a convention for .description() as the name of the Error variant: say, enum MyError { FooBar() } should be implemented as impl Error for MyError { fn description() { println!("foo bar") };.
The nice thing about this is that in future versions of rustc, the description method can be auto-implemented by the compiler (converting CamelCase to space-delimited lower case, or whatever is deemed appropriate, with non-conforming names to be passed through verbatim). The Error trait could have an overridable default implementation of description (conforming to the above) as cause does today, with the difference being, in description's case, the intent would be to soft-deprecate it my making something the user no longer has to think about.
If this makes sense, let me know and I'll open a related issue with error-chain--as the defacto standard crate for error handling in Rust, having it auto-implement description according to a simple convention such as this would be an easy way to start down the road to a fix.
:+1: to deprecating description and just staying with cause. I'd much rather errors describe more about the error in the type and the Display implementation, and use cause for some reasonable form of stack-tracing.
IMHO we could probably get away with actually deprecating description calls (but not definitions) and providing a default impl of unimplemented!()
I'd probably lean towards a default impl of some string literal but I'm definitely on board with deprecating description.
description is useful when you cannot or would rather not to allocate space for formatted string. I鈥檝e used it this way a few times.
Would CrateName::ErrorName::MyError be a good default description? Obviously, anyone wanting a richer description could impl Error for ErrorName and override the default description.
@nagisa: Is it definitely impossible to implement Display without allocating for a String within the fmt method? Does this allocate for a String for sure?
impl fmt::Display for MyError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "My description. ")
}
}
Considering that description has been deprecated, I'll close this issue as well since the initial "issue" got solved. :)
Most helpful comment
:+1: to deprecating
descriptionand just staying withcause. I'd much rather errors describe more about the error in the type and theDisplayimplementation, and usecausefor some reasonable form of stack-tracing.IMHO we could probably get away with actually deprecating
descriptioncalls (but not definitions) and providing a default impl ofunimplemented!()