diff --git a/kernel/src/error.rs b/kernel/src/error.rs index 832e2e994..777ced75a 100644 --- a/kernel/src/error.rs +++ b/kernel/src/error.rs @@ -10,6 +10,10 @@ pub type DeltaResult = std::result::Result; #[derive(thiserror::Error, Debug)] pub enum Error { + // This is an error that includes a backtrace. To have a particular type of error include such + // backtrace (when RUST_BACKTRACE=1), annotate the error with `#[error(transparent)]` and then + // add the error type and enum variant to the `from_with_backtrace!` macro invocation below. See + // IOError for an example. #[error("{source}\n{backtrace}")] Backtraced { source: Box, @@ -35,8 +39,8 @@ pub enum Error { source: Box, }, - #[error("IO error: {0}")] - IOError(#[from] std::io::Error), + #[error(transparent)] + IOError(std::io::Error), #[cfg(feature = "parquet")] #[error("Arrow error: {0}")] @@ -73,8 +77,8 @@ pub enum Error { #[error("Invalid url: {0}")] InvalidUrl(#[from] url::ParseError), - #[error("Invalid url: {0}")] - MalformedJson(#[from] serde_json::Error), + #[error(transparent)] + MalformedJson(serde_json::Error), #[error("No table metadata found in delta log.")] MissingMetadata, @@ -144,6 +148,23 @@ impl Error { } } +macro_rules! from_with_backtrace( + ( $(($error_type: ty, $error_variant: ident)), * ) => { + $( + impl From<$error_type> for Error { + fn from(value: $error_type) -> Self { + Self::$error_variant(value).with_backtrace() + } + } + )* + }; +); + +from_with_backtrace!( + (serde_json::Error, MalformedJson), + (std::io::Error, IOError) +); + #[cfg(any(feature = "default-client", feature = "sync-client"))] impl From for Error { fn from(value: arrow_schema::ArrowError) -> Self {