Reputation: 4146
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:
#[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?
Upvotes: 3
Views: 2995
Reputation: 15071
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
}
}
Upvotes: 7