While this question is about the miette library, it could probably be answered by every experienced Rustacean by looking at the miette sourcecode. It isn't that big, but I wasn't able to extract the answer from it, sadly.
All the following examples assume the dependencies:
miette = { version = "4.4", features = ["fancy"] }
thiserror = "1.0"
I currently have a custom error definition similar to the following in my library tokio-graceful-shutdown:
#[derive(Debug, thiserror::Error, miette::Diagnostic)]
pub enum MyError {
#[error("Error containing another error")]
AnError(#[source] Box<dyn Error + Send + Sync>),
}
I would like the source error type to be generic, with a default value of Box<dyn Error>
.
My attempts
If I would leave out the miette::Diagnostic
, the solution would look like this:
#[derive(Debug, thiserror::Error)]
pub enum MyError<ErrType = Box<dyn Error + Send + Sync>> {
#[error("Error containing another error")]
AnError(#[source] ErrType),
}
If I would leave out the Box<dyn Error>
default value, the solution would look like this:
#[derive(Debug, thiserror::Error, miette::Diagnostic)]
pub enum MyError<ErrType: 'static + Error> {
#[error("Error containing another error")]
AnError(#[source] ErrType),
}
Sadly, combining the two, it turns out that Box<dyn Error>
does NOT implement Error
:
#[derive(Debug, thiserror::Error, miette::Diagnostic)]
pub enum MyError<ErrType: 'static + Error = Box<dyn Error + Send + Sync>> {
#[error("Error containing another error")]
AnError(#[source] ErrType),
}
|
| pub enum MyError<ErrType: 'static + Error = Box<dyn Error + Send + Sync>> {
| ^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `(dyn std::error::Error + Send + Sync + 'static)`
= note: required because of the requirements on the impl of `std::error::Error` for `Box<(dyn std::error::Error + Send + Sync + 'static)>`
I suspect, however, that this error message is a red herring and instead, the 'static + Error
is incorrect and ErrType
needs a different restriction.
The reason why I suspect this is that if I directly use Box<dyn Error>
as the source type, it works, as in the first example. That makes me believe that it isn't actually Error
that miette::Diagnostic
requires to work.
Final question
(which is hopefully not susceptible to the XY problem)
What should be inserted at the <???>
placeholder to make the following code compile?
#[derive(Debug, thiserror::Error, miette::Diagnostic)]
pub enum MyError<ErrType: <???> = Box<dyn Error + Send + Sync>> {
#[error("Error containing another error")]
AnError(#[source] ErrType),
}