Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to use thiserror to forward an error with a generic type parameter

Learning Rust, I am using the thiserror crate to wrap some exceptions.

This is the exception I want to wrap from the unrar crate:

#[derive(PartialEq)]
pub struct UnrarError<T> {
    pub code: Code,
    pub when: When,
    pub data: Option<T>,
}

My own code is this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

#[derive(Debug, Error)]
pub enum MyError {

    #[error(transparent)]
    Io(#[from] io::Error),

    #[error(transparent)]
    Unrar(#[from] unrar::error::UnrarError), // <-- missing generics

    #[error("directory already exists")]
    DirectoryExists,
}

The compiler complains about the missing generics type parameter on the UnrarError.

So I can add a type parameter:

#[derive(Debug, Error)]
pub enum MyError<T> {

    #[error(transparent)]
    Io(#[from] io::Error),

    #[error(transparent)]
    Unrar(#[from] unrar::error::UnrarError<T>),

    #[error("directory already exists")]
    DirectoryExists,
}

But if I do this, now all of my code that uses MyError needs to care about this type parameter, which in practical terms none of it cares about.

How should I idiomatically handle this situation?

>Solution :

I recommend you to use specific types or add your own variant. The UnrarError is designed to be generic where is shouldn’t be generic.

Try the following:

#[derive(Debug, Error)]
pub enum MyError {

    #[error(transparent)]
    Io(#[from] io::Error),

    #[error(transparent)]
    Unrar(#[from] unrar::error::UnrarError<OpenArchive>),

    #[error(transparent)]
    UnrarProcessing(#[from] unrar::error::UnrarError<Vec<Entry>>),

    #[error("directory already exists")]
    DirectoryExists,
}

Or how I prefer to do in this case:

#[derive(Debug, Error)]
pub enum MyError {

    #[error(transparent)]
    Io(#[from] io::Error),

    #[error("unrar error")]
    Unrar,

    #[error("directory already exists")]
    DirectoryExists,
}

impl<T> From<unrar::error::UnrarError<T>> for MyError {
    fn from(err: unrar::error::UnrarError<T>) -> Self {
        // Get details from the error you want,
        // or even implement for both T variants.
        Self::Unrar
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading