use tracing_error::{SpanTrace, SpanTraceStatus}; pub type StdError = Box; pub type Result = std::result::Result; #[derive(Debug)] pub struct Error { inner: Box, span_trace: SpanTrace, } impl Error { /// Create a new error from a `std::error::Error`. #[must_use] #[track_caller] pub fn new(source: T) -> Self { Self::from_std_error(source.into()) } /// Create a new error from a `std::error::Error`. #[must_use] #[track_caller] pub fn from_std_error(inner: StdError) -> Self { Self { inner, span_trace: SpanTrace::capture(), } } /// Create a new error from a string. #[must_use] #[track_caller] pub fn from_string(s: impl Into) -> Self { Self::msg(s) } /// Create a new error from a string. #[must_use] #[track_caller] pub fn msg(s: impl Into) -> Self { Self::from_std_error(s.into().into()) } /// Returns `true` if the inner type is the same as `T`. #[inline] pub fn is(&self) -> bool { self.inner.is::() } /// Returns some reference to the inner value if it is of type `T`, or /// `None` if it isn't. #[inline] pub fn downcast_ref(&self) -> Option<&T> { self.inner.downcast_ref() } /// Returns some mutable reference to the inner value if it is of type `T`, or /// `None` if it isn't. #[inline] pub fn downcast_mut(&mut self) -> Option<&mut T> { self.inner.downcast_mut() } } impl From for Error { fn from(e: T) -> Self { Self::new(e) } } impl std::fmt::Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.inner)?; if self.span_trace.status() != SpanTraceStatus::EMPTY { write!(f, "\nspan_trace:\n{}", self.span_trace)?; } Ok(()) } }