I’ve spent a lot of time now trying to make libraries that simplify Rust’s error handling, and am super frustrated. It feels like things fit together in ways that require needless complexity for the end user. I am constantly being thwarted and forced to add extra conversion methods and special cases to work around the type system. You may be aware of my error-chain crate, which I think is the easiest way to deal with errors in Rust today - and it is still really complicated and requires users to understand how to do conversions correctly in several cases.
What I’ve been trying to do today is create the simplest possible library for dealing with errors correctly, one that doesn’t require newbies to understand details of all the traits and conversions around Error. The obvious way to do this is to use boxed Error + Send
everywhere, but I can’t figure out how to do it.
Here’s some really simple code that would make ?
automatically convert Result
of any type implementing Error
into a local error type. Of course it doesn’t work.
use std::result::Result as StdResult;
use std::error::Error as StdError;
use std::io::{self, Write};
use std::fmt;
pub type EzResult<T> = StdResult<T, EzError>;
#[derive(Debug)]
pub struct EzError(Box<StdError + Send>);
impl StdError for EzError {
fn description(&self) -> &str { self.0.description() }
fn cause(&self) -> Option<&StdError> { self.0.cause() }
}
impl fmt::Display for EzError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.fmt(f) }
}
impl<E> From<E> for EzError
where E: StdError + Send
{
fn from(e: E) -> EzError {
EzError(Box::new(e))
}
}
Try to compile this and there’s a conflicting implementation in core. What is that impl?
Is there any way to make ?
automatically box any Error?