1use std::{
5 backtrace::{Backtrace, BacktraceStatus},
6 error::Error,
7 fmt,
8};
9use tracing_error::{SpanTrace, SpanTraceStatus};
10
11#[derive(Debug)]
15pub struct Failure<E> {
16 error: E,
17 backtrace: Backtrace,
18 span_trace: Option<String>,
19}
20
21impl<E> Failure<E> {
22 pub fn capture(error: E) -> Self {
24 Self::with_backtrace(error, Backtrace::capture())
25 }
26
27 pub fn with_backtrace(error: E, backtrace: Backtrace) -> Self {
29 let trace = SpanTrace::capture();
30 let span_trace = (trace.status() == SpanTraceStatus::CAPTURED).then(|| trace.to_string());
31 Self {
32 error,
33 backtrace,
34 span_trace,
35 }
36 }
37
38 pub fn error(&self) -> &E {
40 &self.error
41 }
42
43 pub fn backtrace(&self) -> &Backtrace {
45 &self.backtrace
46 }
47
48 pub fn span_trace(&self) -> Option<&str> {
50 self.span_trace.as_deref()
51 }
52
53 pub fn into_inner(self) -> E {
55 self.error
56 }
57}
58
59impl<E> Failure<E> {
60 pub fn captured_backtrace(&self) -> Option<&Backtrace> {
62 (self.backtrace.status() == BacktraceStatus::Captured).then_some(&self.backtrace)
63 }
64}
65
66impl<E: fmt::Display> fmt::Display for Failure<E> {
67 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
68 self.error.fmt(formatter)
69 }
70}
71
72impl<E: Error + 'static> Error for Failure<E> {
73 fn source(&self) -> Option<&(dyn Error + 'static)> {
74 self.error.source()
75 }
76}