diff --git a/rs-matter/src/error.rs b/rs-matter/src/error.rs index 5527e1f..28e7b67 100644 --- a/rs-matter/src/error.rs +++ b/rs-matter/src/error.rs @@ -85,6 +85,8 @@ pub struct Error { code: ErrorCode, #[cfg(all(feature = "std", feature = "backtrace"))] backtrace: std::backtrace::Backtrace, + #[cfg(all(feature = "std", feature = "backtrace"))] + inner: Option>, } impl Error { @@ -93,6 +95,22 @@ impl Error { code, #[cfg(all(feature = "std", feature = "backtrace"))] backtrace: std::backtrace::Backtrace::capture(), + #[cfg(all(feature = "std", feature = "backtrace"))] + inner: None, + } + } + + #[cfg(all(feature = "std", feature = "backtrace"))] + pub fn new_with_details( + code: ErrorCode, + detailed_err: Box, + ) -> Self { + Self { + code, + #[cfg(all(feature = "std", feature = "backtrace"))] + backtrace: std::backtrace::Backtrace::capture(), + #[cfg(all(feature = "std", feature = "backtrace"))] + inner: Some(detailed_err), } } @@ -105,6 +123,11 @@ impl Error { &self.backtrace } + #[cfg(all(feature = "std", feature = "backtrace"))] + pub fn details(&self) -> Option<&(dyn std::error::Error + Send)> { + self.inner.as_ref().map(|err| err.as_ref()) + } + pub fn remap(self, matcher: F, to: Self) -> Self where F: FnOnce(&Self) -> bool, @@ -136,10 +159,16 @@ impl Error { } } -#[cfg(feature = "std")] +#[cfg(all(feature = "std", feature = "backtrace"))] +impl From for Error { + fn from(e: std::io::Error) -> Self { + Self::new_with_details(ErrorCode::StdIoError, Box::new(e)) + } +} + +#[cfg(all(feature = "std", not(feature = "backtrace")))] impl From for Error { fn from(_e: std::io::Error) -> Self { - // Keep things simple for now Self::new(ErrorCode::StdIoError) } } @@ -221,7 +250,21 @@ impl fmt::Debug for Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?}", self.code()) + #[cfg(all(feature = "std", feature = "backtrace"))] + { + write!( + f, + "{:?}: {}", + self.code(), + self.inner + .as_ref() + .map_or(String::new(), |err| { err.to_string() }) + ) + } + #[cfg(not(all(feature = "std", feature = "backtrace")))] + { + write!(f, "{:?}", self.code()) + } } }