lhgzbxhz
lhgzbxhz

Reputation: 55

How to include PoisonError in my own error type

(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

Upvotes: 4

Views: 1161

Answers (1)

Kevin Reid
Kevin Reid

Reputation: 43982

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"))
    }
}

Upvotes: 6

Related Questions