I used to use error-chain and failure, but I tend to just write my errors directly now, so I have control over how they work. A simple error would be something like
#[derive(Debug)]
pub enum MyError {
CannotOpenFile(io::Error),
CannotReadData(io::Error),
// ...
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
MyError::CannotOpenFile(e) => write!(f, "error while opening file: {}", e),
// ....
}
}
}
impl Error for MyError {
fn source(&self) -> &dyn Error {
match self {
MyError::CannotOpenFile(e) => e,
// ...
}
}
}
You don't have to impl the source method if you think the fmt msg is enough, in which case you'd have
impl Error for MyError {}
which is a bit shorter