summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Orlenko <zxteam@protonmail.com>2023-05-08 23:39:53 +0100
committerAlex Orlenko <zxteam@protonmail.com>2023-05-08 23:39:53 +0100
commit1ac98e7d16a9a3739c369f5c88b6d83798997c0c (patch)
tree1433834f25937f9c3208bad259f95130b5b875b5 /src
parentbbd2fe06e1161d8ddb5074602723be65aebbf851 (diff)
downloadmlua-1ac98e7d16a9a3739c369f5c88b6d83798997c0c.zip
- Allow downcasting error wrapped into `Error::WithContext`
- Overwrite error context when called multiple times
Diffstat (limited to 'src')
-rw-r--r--src/error.rs38
1 files changed, 24 insertions, 14 deletions
diff --git a/src/error.rs b/src/error.rs
index 3ccff0e..cfdd19a 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -335,6 +335,10 @@ impl StdError for Error {
// Given that we include source to fmt::Display implementation for `CallbackError`, this call returns nothing.
Error::CallbackError { .. } => None,
Error::ExternalError(ref err) => err.source(),
+ Error::WithContext { ref cause, .. } => match cause.as_ref() {
+ Error::ExternalError(err) => err.source(),
+ _ => None,
+ },
_ => None,
}
}
@@ -353,6 +357,10 @@ impl Error {
{
match self {
Error::ExternalError(err) => err.downcast_ref(),
+ Error::WithContext { cause, .. } => match cause.as_ref() {
+ Error::ExternalError(err) => err.downcast_ref(),
+ _ => None,
+ },
_ => None,
}
}
@@ -414,33 +422,35 @@ pub trait ErrorContext: Sealed {
impl ErrorContext for Error {
fn context<C: fmt::Display>(self, context: C) -> Self {
- Error::WithContext {
- context: context.to_string(),
- cause: Arc::new(self),
+ let context = context.to_string();
+ match self {
+ Error::WithContext { cause, .. } => Error::WithContext { context, cause },
+ _ => Error::WithContext {
+ context,
+ cause: Arc::new(self),
+ },
}
}
fn with_context<C: fmt::Display>(self, f: impl FnOnce(&Error) -> C) -> Self {
- Error::WithContext {
- context: f(&self).to_string(),
- cause: Arc::new(self),
+ let context = f(&self).to_string();
+ match self {
+ Error::WithContext { cause, .. } => Error::WithContext { context, cause },
+ _ => Error::WithContext {
+ context,
+ cause: Arc::new(self),
+ },
}
}
}
impl<T> ErrorContext for StdResult<T, Error> {
fn context<C: fmt::Display>(self, context: C) -> Self {
- self.map_err(|err| Error::WithContext {
- context: context.to_string(),
- cause: Arc::new(err),
- })
+ self.map_err(|err| err.context(context))
}
fn with_context<C: fmt::Display>(self, f: impl FnOnce(&Error) -> C) -> Self {
- self.map_err(|err| Error::WithContext {
- context: f(&err).to_string(),
- cause: Arc::new(err),
- })
+ self.map_err(|err| err.with_context(f))
}
}