fatality
A generative approach to creating fatal and non-fatal errors.
The generated source utilizes thiserror::Error derived attributes heavily,
and any unknown annotations will be passed to that.
Motivation
For large scale mono-repos, with subsystems it eventually becomes very tedious to match
against nested error variants defined with thiserror. Using anyhow or eyre - while it being an application - also comes with an unmanagable amount of pain for medium-large scale code bases.
fatality is a solution to this, by extending thiserror::Error with annotations to declare certain variants as fatal, or forward the fatality extraction to an inner error type.
Read on!
Usage
#[fatality] currently provides a trait Fatality with a single fn is_fatal(&self) -> bool by default.
Annotations with forward require the inner error type to also implement trait Fatality.
Annotating with #[fatality(splitable)], allows to split the type into two sub-types, a Jfyi* and a Fatal* one via fn split(self) -> Result<Self::Jfyi, Self::Fatal>. If splitable is annotated.
The derive macro implements them, and can defer calls, based on thiserror annotations, specifically
#[source] and #[transparent] on enum variants and their members.
/// Fatality only works with `enum` for now.
/// It will automatically add `#[derive(Debug, thiserror::Error)]`
/// annotations.
Roadmap
- Optionally reduce the marco overhead, replace
#[fatal($args)]#[error(..with#[fatal($args;..)]and generate the correct#[error]annotations forthiserror. - Add an optional arg to
finality:splitabledetermines if a this is the root error that shall be handled, and hence should be splitable into two enumsFatalandJfyierrors, withtrait Splitandfn split() -> Result<Jfyi, Fatal> {..}. - Allow annotations for
structs as well, to be all fatal or informational.