Merge pull request #93 from ssnover/std-box-dyn-error

Add a boxed dyn error to make error info easier to access on hosted systems
This commit is contained in:
Kedar Sovani 2023-09-25 22:35:58 +05:30 committed by GitHub
commit 0fe4ae906f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -85,6 +85,8 @@ pub struct Error {
code: ErrorCode, code: ErrorCode,
#[cfg(all(feature = "std", feature = "backtrace"))] #[cfg(all(feature = "std", feature = "backtrace"))]
backtrace: std::backtrace::Backtrace, backtrace: std::backtrace::Backtrace,
#[cfg(all(feature = "std", feature = "backtrace"))]
inner: Option<Box<dyn std::error::Error + Send>>,
} }
impl Error { impl Error {
@ -93,6 +95,22 @@ impl Error {
code, code,
#[cfg(all(feature = "std", feature = "backtrace"))] #[cfg(all(feature = "std", feature = "backtrace"))]
backtrace: std::backtrace::Backtrace::capture(), 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<dyn std::error::Error + Send>,
) -> 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 &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<F>(self, matcher: F, to: Self) -> Self pub fn remap<F>(self, matcher: F, to: Self) -> Self
where where
F: FnOnce(&Self) -> bool, F: FnOnce(&Self) -> bool,
@ -136,10 +159,16 @@ impl Error {
} }
} }
#[cfg(feature = "std")] #[cfg(all(feature = "std", feature = "backtrace"))]
impl From<std::io::Error> 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<std::io::Error> for Error { impl From<std::io::Error> for Error {
fn from(_e: std::io::Error) -> Self { fn from(_e: std::io::Error) -> Self {
// Keep things simple for now
Self::new(ErrorCode::StdIoError) Self::new(ErrorCode::StdIoError)
} }
} }
@ -221,8 +250,22 @@ impl fmt::Debug for Error {
impl fmt::Display for Error { impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
#[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()) write!(f, "{:?}", self.code())
} }
}
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]