Conventions and enhancements of Error trait


#1

Hi,

I’d like to propose conventions for and enhancements of std::error::Error trait.

  • .description() and .detail() should contain only single-line messages, i. e. without \n characters (so program output won’t be garbled)
  • .detail() is expected to be appended to .description(), not used instead of it
  • Error trait should extend Show
  • Default implementation of Show should be this:
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
    match self.detail() {
        Some(detail) => try!(write!(fmt, "{} ({})", self.description(), detail)),
        None => try!(write!(fmt, "{}", self.description())),
    };
    match self.cause() {
        Some(cause) => write!(fmt, " caused by: {}", cause),
        None => Ok(()),
    }
}

I propose conventions to be added to rustdoc of Error trait. AFAIU default impementation of Show for Error is not possible in current rust, so default fmt can be implemented like this:

impl Error {
    fn default_fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { ... }
}

so any type extending Error trait can reuse default_fmt to implement Show.

Note, that because default_fmt outputs the whose cause chain, so it may output really long message in single line. I think that’s OK, because usually it is important to provide as much error details as possible.

What do you think?


#2

I support this. There are no clear guidelines on what should be in detail, and most implementations in the Rust libraries delegate it to fmt, which typically is a more or less close copy of the messages in description plus some formatting for dynamic data. This makes for poor UI choices in presenting the error: instead of three differently detailed strings, there are in effect two partially redundant ones.

Do you care to submit this as an RFC draft?

Perhaps rather than default_fmt writing the chain in line, there could be a helper function to pretty-print the error into a Writer in multiple lines.