From c443a72b42a0ac25faa6a69e9d96154b14c6648f Mon Sep 17 00:00:00 2001 From: ssnover Date: Tue, 29 Aug 2023 15:04:58 -0600 Subject: [PATCH] Add a boxed dyn error to make error info easier to access on hosted systems --- rs-matter/src/error.rs | 49 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/rs-matter/src/error.rs b/rs-matter/src/error.rs index 91ba77e4..64e16804 100644 --- a/rs-matter/src/error.rs +++ b/rs-matter/src/error.rs @@ -83,6 +83,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 { @@ -91,6 +93,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), } } @@ -103,6 +121,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, @@ -134,10 +157,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) } } @@ -219,7 +248,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()) + } } }