I have a problem implementing the Error
trait. I want to wrap an error from Diesel or another database driver. I didn't even get close to implementing From
since I'm already failing at implementing Error
. The line that causes the code not to compile is the one at the very end of the code block.
use std::fmt;
use std::error::{self, Error};
#[derive(Debug)]
pub enum MyError {
NotFound(String),
PersistenceError(Box<Error + Send + Sync>),
}
pub type MyResult<T> = Result<T, MyError>;
impl fmt::Display for MyError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
MyError::NotFound(ref msg) => write!(f, "Not found: {}", msg),
MyError::PersistenceError(ref cause) => write!(f, "Persistence error: {}", cause),
}
}
}
impl Error for MyError {
fn description(&self) -> &str {
match *self {
MyError::NotFound(ref msg) => msg,
MyError::PersistenceError(ref cause) => cause.description(),
}
}
fn cause(&self) -> Option<&Error> {
match *self {
MyError::NotFound(_) => None,
// `*cause` does not live long enough
MyError::PersistenceError(cause) => Some(&*cause),
}
}
}
I also tried:
*cause does not live long enough
MyError::PersistenceError(cause) => Some(&*cause),
the trait core::marker::Sized is not implemented for the type std::error::Error + Send + Sync + 'static [E0277]
MyError::PersistenceError(ref cause) => Some(cause),
the trait std::error::Error is not implemented for the type `&Box
MyError::PersistenceError(ref cause) => Some(&cause)
But none of these worked.
It is useful to print the type of variables in cases like this:
match *self {
MyError::NotFound(_) => None,
MyError::PersistenceError(ref cause) => {
let () = cause;
},
}
This will tell you that cause
is a &Box<std::error::Error + Send + Sync>
.
If we dereference it once, we will have a Box<std::error::Error + Send + Sync>
and if we dereference it a second time we will have a std::error::Error + Send + Sync
(this isn't a real type). We can then take another reference which can be implicitly made into an &Error
:
match *self {
MyError::NotFound(_) => None,
MyError::PersistenceError(ref cause) => Some(&**cause),
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With