diff options
author | Alex Orlenko <zxteam@protonmail.com> | 2023-05-08 23:39:53 +0100 |
---|---|---|
committer | Alex Orlenko <zxteam@protonmail.com> | 2023-05-08 23:39:53 +0100 |
commit | 1ac98e7d16a9a3739c369f5c88b6d83798997c0c (patch) | |
tree | 1433834f25937f9c3208bad259f95130b5b875b5 /src | |
parent | bbd2fe06e1161d8ddb5074602723be65aebbf851 (diff) | |
download | mlua-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.rs | 38 |
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)) } } |