(English is not my native language; please excuse typing errors.)
In my project thers is an error type:
pub type RvzResult<T> = Result<T, RvzError>;
#[derive(Error, Debug)]
pub enum RvzError {
// some error types...
,
OtherErr(Box<dyn Error>)
}
One day I had a Mutex object and used it like this:
pub fn some_func() -> RvzResult<()> {
// ...
let lock = the_mutex.lock()?;
// ...
}
But rustc wasn't so happy:error[E0277]: '?' couldn't convert the error to 'RvzError'
I tried to impl From trait like this:
impl <T> From<PoisonError<T>> for RvzError {
fn from(err: PoisonError<T>) -> Self {
Self::OtherErr(Box::new(err))
}
}
It failed:error[E0310]: the parameter type 'T' may not live long enough
A PoisonError is not just an error code, but has a special function: it allows you to bypass the lock-poisoning check and access the data anyway. The <T> parameter of PoisonError is the lock guard object that it can be asked to return, so the PoisonError in your function is a borrow of the_mutex.
Therefore, it cannot be made into a Box<dyn Error> (which is implicitly + 'static) and should not be returned from some_func() anyway. Instead, create a new error which doesn't try to contain the original PoisonError value — either a variant of RvzError:
impl<T> From<PoisonError<T>> for RvzError {
fn from(err: PoisonError<T>) -> Self {
Self::Poison
}
}
Or a boxed string error (using this impl):
impl<T> From<PoisonError<T>> for RvzError {
fn from(_: PoisonError<T>) -> Self {
Self::OtherErr(Box::<dyn Error>::from("PoisonError"))
}
}
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