Someone suggested that I post this here and link it back to the original reddit post, so I'm doing that. Here's the link: Is there a crate like this? : rust (reddit.com)
It finally occurred to me to ask before I kept implementing this. Is there an error crate that generates a "tree" of errors? Something that looks like:
error_tree! {
UnifiedError {
"internal: {}"
Internal: {
Frontend: {
Discord: @nogen SerenityError,
DiscordBadInteraction,
},
Sim: Sirror {
@nofrom MultipleStatusLoadFailed: @nogen Vec<StatusKind>,
MissingComponent: (EntityKind, @nogen Cow<'static, str>),
},
BadConfig: ConfigSource,
Unknown,
},
@nodisplay User {
@nofrom BadState: String,
SomethingElse: @nogen CustomError,
LackingItems: @struct {
somethingelse: AnotherErrorTree,
message_maybe: String,
},
},
}
}
and generates
use thiserror::Error;
#[derive(Error)]
pub enum UnifiedError {
#[error("internal: {}"]
Internal(InternalError),
#[error(transparent)]
User(UserError).
}
from_impl!(UnifiedError = User(UserError));
from_impl!(UnifiedError = Internal(InternalError));
#[derive(Error)]
pub enum InternalError {
#[error(transparent)]
Frontend(FrontendError),
#[error(transparent)]
Sim(Sirror),
#[error(transparent)]
BadConfig(ConfigSource),
#[error(transparent)]
Unknown,
}
from_impl!(InternalError = Frontend(FrontendError));
from_impl!(InternalError = Sim(Sirror));
from_impl!(InternalError = BadConfig(ConfigSource));
#[derive(Error)]
pub enum FrontendError {
#[error(transparent)]
Discord(SerenityError),
#[error(transparent)]
DiscordBadInteraction,
}
#[derive(Error)]
pub enum Sirror {
MultipleStatusLoadFailed(Vec<StatusKind>)
MissingComponent(Dunno, Cow<'static, str>),
}
from_impl!(Sirror = MultipleStatusLoadFailed(Vec<StatusKind>));
impl From<(Dunno, Cow<'static, str>)> for Sirror {
fn from((a, b): (Dunno, Cow<'static, str>)) -> Self {
Sirror::MissingComponent(a, b)
}
}
#[derive(Error)]
pub struct Dunno;
#[derive(Error)]
pub enum UserError {
BadState(String),
SomethingElse(CustomError),
LackingItems {
lacking: Vec<LackingItem>,
command: String,
},
}
from_impl!(UserError = SomethingElse(CustomError));
from_many!(UnifiedError : Internal [
Sirror, FrontendError, ConfigSource, Sirror,
(Dunno, Cow<'static, str>)
]);
from_many!(UnifiedError : User [
CustomError,
]);
because I almost finished implementing it, but it's got all kinds of rough edges. If one already exists, I'd rather use that than work through all the issues/features.