-
-
Notifications
You must be signed in to change notification settings - Fork 129
Description
I would like to understand where miette currently tries to position itself in the 'Rust error story'. To do this, I'm opening this issue to see what I might have missed and/or not understood correctly.
Miette exposes a Diagnostic
trait that extends on top of the Error
trait with additional information so as to report better looking and more informative errors.
To do so, it currently imposes the following relationship Diagnostic: StdError
(StdError
is a supertrait of Diagnostic
). This means that any Diagnostic
is also an StdError
.
StdError
has multiple advantages that speak for it:
- It requires a 'Display' implementation, forcing developers to give a textual representation of the error that is fit for 'end-user consumption'.
- It has a
.source/cause
method that gives access to the error that 'cause'd it
Diagnostic
builds on top of this with the ability to specify spans with labels, severity, etc... .
This gives it several nice things that seperate it from StdError
:
- Users can be more precisely informed with visual language on where errors occured
- Colors (through severity) give them a color indicator on how 'bad' or useful the information is
- Through the
.source
method ofStdError
on can get access to the underlying errors and print those too, potentially going as far as to the root error that caused it.
This means that for a given Diagnostic
and finally Report
one can have the following relationship:
┌────────┐
┌───────┤ Report ├────┐
│ └────────┘ │
│ │
│ │
┌────▼─────┐ ┌────▼─────┐
│Diagnostic│ │Diagnostic│
└────┬─────┘ └─────┬────┘
│ │
│ │
│ │
┌───▼────┐ ┌────▼───┐
│StdError│ │StdError│
└────────┘ └────┬───┘
│
│
│
┌────▼───┐
│StdError│
└────────┘
Important to note is that while the Top-level Diagnostic/Report has multiple 'Diagnostics' below it, they are currently only 'related'. (For example multiple logically distinct errors in a configuration file).
It is also not possible to 'chain' Diagnostics, as there is no .source
equivalent for Diagnostic
. This means that either a single diagnostic is created at the root (potentially wrapping a StdError) and then transported all the way to the base or that extra information is added later on. (Through for example the with_source_code
transforms). An error, once made into a Diagnostic
cannot be re-integrated into the chain of errors except as a logically distinct 'related' issue.
To me, this disconnect feels weird (and is mostly due to Rust constraints from its current state). I was expecting that I could effectively represent a 'tree' of Diagnostics
with the following relationship:
┌────────┐
┌───────┤ Report ├────┐
│ └────────┘ │
│ │
│ │
┌────▼─────┐ ┌────▼─────┐
│Diagnostic│ │Diagnostic├────────┐
└────┬─────┘ └────┬─────┘ │
│ │ │
│ │ │
│ │ │
┌────────┐ ┌────▼─────┐ ┌────▼─────┐ ┌────▼─────┐ ┌────────┐
│StdError├──►Diagnostic│ │Diagnostic│ │Diagnostic◄───┤StdError│
└────────┘ └──────────┘ └────┬─────┘ └──────────┘ └────────┘
│
│
│
┌────▼─────┐
│Diagnostic│
└──────────┘
Where any StdError
could be converted to a Diagnostic
to be used as part of the tree of errors an application may expose but that Diagnostic
does not require the supertrait Error
anymore.
This brings its own problems with it though, as now libraries that expose a Diagnostic
has no direct compatibility to std::error::Error
.
From what I understand, this is currently heavily geared towards maximum compatibility with the StdError
ecosystem but at the same time Report
does not implement StdError
anyway.
This leaves me wondering, why does Diagnostic require Error
as a supertrait? If one wants to keep compatibility with StdError
then one can just implement it (with thiserror
or manually). If Diagnostic
simply has a Display
bound, then they are even compatible together (since thiserror
implements Display for you too).
NB: English is not my first language, and I hope I didn't miss my tone here: I am trying to understand how Miette came to be and where it would like to be in the future?
This is maybe related to #139?
I am using StdError
to disambiguate on "Error"