Add `ErrorContext` extension trait to attach additional context to `Error`
This commit is contained in:
parent
a0d37fd182
commit
8d80321738
49
src/error.rs
49
src/error.rs
|
@ -7,6 +7,8 @@ use std::str::Utf8Error;
|
|||
use std::string::String as StdString;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::private::Sealed;
|
||||
|
||||
/// Error type returned by `mlua` methods.
|
||||
#[derive(Debug, Clone)]
|
||||
#[non_exhaustive]
|
||||
|
@ -190,6 +192,11 @@ pub enum Error {
|
|||
/// error. The Rust code that originally invoked the Lua code then receives a `CallbackError`,
|
||||
/// from which the original error (and a stack traceback) can be recovered.
|
||||
ExternalError(Arc<dyn StdError + Send + Sync>),
|
||||
/// An error with additional context.
|
||||
WithContext {
|
||||
context: StdString,
|
||||
cause: Arc<Error>,
|
||||
},
|
||||
}
|
||||
|
||||
/// A specialized `Result` type used by `mlua`'s API.
|
||||
|
@ -306,6 +313,10 @@ impl fmt::Display for Error {
|
|||
write!(fmt, "deserialize error: {err}")
|
||||
},
|
||||
Error::ExternalError(ref err) => write!(fmt, "{err}"),
|
||||
Error::WithContext { ref context, ref cause } => {
|
||||
writeln!(fmt, "{context}")?;
|
||||
write!(fmt, "{cause}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -374,6 +385,44 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Provides the `context` method for [`Error`] and `Result<T, Error>`.
|
||||
pub trait ErrorContext: Sealed {
|
||||
fn context<C: fmt::Display>(self, context: C) -> Self;
|
||||
fn with_context<C: fmt::Display>(self, f: impl FnOnce(&Error) -> C) -> Self;
|
||||
}
|
||||
|
||||
impl ErrorContext for Error {
|
||||
fn context<C: fmt::Display>(self, context: C) -> Self {
|
||||
Error::WithContext {
|
||||
context: context.to_string(),
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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),
|
||||
})
|
||||
}
|
||||
|
||||
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),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<AddrParseError> for Error {
|
||||
fn from(err: AddrParseError) -> Self {
|
||||
Error::external(err)
|
||||
|
|
11
src/lib.rs
11
src/lib.rs
|
@ -108,7 +108,7 @@ pub mod prelude;
|
|||
pub use crate::{ffi::lua_CFunction, ffi::lua_State};
|
||||
|
||||
pub use crate::chunk::{AsChunk, Chunk, ChunkMode};
|
||||
pub use crate::error::{Error, ExternalError, ExternalResult, Result};
|
||||
pub use crate::error::{Error, ErrorContext, ExternalError, ExternalResult, Result};
|
||||
pub use crate::function::{Function, FunctionInfo};
|
||||
pub use crate::hook::{Debug, DebugEvent, DebugNames, DebugSource, DebugStack};
|
||||
pub use crate::lua::{GCMode, Lua, LuaOptions};
|
||||
|
@ -232,3 +232,12 @@ pub use mlua_derive::chunk;
|
|||
#[cfg(any(feature = "module", docsrs))]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "module")))]
|
||||
pub use mlua_derive::lua_module;
|
||||
|
||||
pub(crate) mod private {
|
||||
use super::*;
|
||||
|
||||
pub trait Sealed {}
|
||||
|
||||
impl Sealed for Error {}
|
||||
impl<T> Sealed for std::result::Result<T, Error> {}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
#[doc(no_inline)]
|
||||
pub use crate::{
|
||||
AnyUserData as LuaAnyUserData, AnyUserDataExt as LuaAnyUserDataExt, Chunk as LuaChunk,
|
||||
Error as LuaError, ExternalError as LuaExternalError, ExternalResult as LuaExternalResult,
|
||||
FromLua, FromLuaMulti, Function as LuaFunction, FunctionInfo as LuaFunctionInfo,
|
||||
GCMode as LuaGCMode, Integer as LuaInteger, IntoLua, IntoLuaMulti,
|
||||
LightUserData as LuaLightUserData, Lua, LuaOptions, MetaMethod as LuaMetaMethod,
|
||||
Error as LuaError, ErrorContext as LuaErrorContext, ExternalError as LuaExternalError,
|
||||
ExternalResult as LuaExternalResult, FromLua, FromLuaMulti, Function as LuaFunction,
|
||||
FunctionInfo as LuaFunctionInfo, GCMode as LuaGCMode, Integer as LuaInteger, IntoLua,
|
||||
IntoLuaMulti, LightUserData as LuaLightUserData, Lua, LuaOptions, MetaMethod as LuaMetaMethod,
|
||||
MultiValue as LuaMultiValue, Nil as LuaNil, Number as LuaNumber, RegistryKey as LuaRegistryKey,
|
||||
Result as LuaResult, StdLib as LuaStdLib, String as LuaString, Table as LuaTable,
|
||||
TableExt as LuaTableExt, TablePairs as LuaTablePairs, TableSequence as LuaTableSequence,
|
||||
|
|
Loading…
Reference in New Issue