flex_error/
tracer.rs

1use core::fmt::Display;
2
3/// An `ErrorMessageTracer` can be used to generically trace
4/// any error detail that implements [`Display`](std::fmt::Display).
5///
6/// The error tracer may add backtrace information when the tracing
7/// methods are called. However since the error detail is required
8/// to only implement `Display`, any existing error trace may be
9/// lost even if the error detail implements `Error` and contains
10/// backtrace, unless the backtrace is serialized in `Display`.
11pub trait ErrorMessageTracer {
12    /// Creates a new error trace, starting from a source error
13    /// detail that implements [`Display`](std::fmt::Display).
14    fn new_message<E: Display>(message: &E) -> Self;
15
16    /// Adds new error detail to an existing trace.
17    fn add_message<E: Display>(self, message: &E) -> Self;
18
19    /// If the `std` feature is enabled, the error tracer
20    /// also provides method to optionally converts itself
21    /// to a `dyn` [`Error`](std::error::Error).
22    #[cfg(feature = "std")]
23    fn as_error(&self) -> Option<&(dyn std::error::Error + 'static)>;
24}
25
26/// An error tracer implements `ErrorTracer<E>` if it supports
27/// more sophisticated error tracing for an error type `E`.
28/// The contraint for `E` depends on the specific error tracer
29/// implementation.
30///
31/// For example, [`EyreTracer`](crate::tracer_impl::eyre::EyreTracer)
32/// and [`AnyhowTracer`](crate::tracer_impl::anyhow::AnyhowTracer) requires
33/// an error type to satisfy `E: Error + Send + Sync + 'static`.
34///
35/// The error tracer also requires ownership of the source error to be
36/// transferred to the error tracer. Because of this, it may not be possible
37/// to extract a source error type to be used as both error detail and
38/// error trace. We also should not expect `E` to implement `Clone`, as
39/// error types such as [`eyre::Report`] do not implement `Clone`.
40pub trait ErrorTracer<E>: ErrorMessageTracer {
41    /// Create a new error trace from `E`, also taking ownership of it.
42    ///
43    /// This calls the underlying methods such as [`eyre::Report::new`]
44    /// and [`anyhow::Error::new`].
45    fn new_trace(err: E) -> Self;
46
47    /// Add a new error trace from `E`. In the current underlying implementation,
48    /// this is effectively still has the same behavior as
49    /// [`ErrorMessageTracer::add_message`]. This is because [`eyre`] and
50    /// [`anyhow`] do not support adding new set of backtraces to an existing
51    /// trace. So effectively, currently the error tracers can track at most
52    /// one backtrace coming from the original error source.
53    fn add_trace(self, err: E) -> Self;
54}