Skip to content

Commit

Permalink
Merge pull request #151 from nicklan/add-error-backtrace
Browse files Browse the repository at this point in the history
Add backtrace option to errors
  • Loading branch information
nicklan committed Apr 3, 2024
2 parents 21d77d0 + fcd8cb0 commit 02acc9c
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 8 deletions.
13 changes: 12 additions & 1 deletion kernel/examples/dump-table/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::HashMap;
use std::process::ExitCode;
use std::sync::Arc;

use arrow::compute::filter_record_batch;
Expand Down Expand Up @@ -40,8 +41,18 @@ enum Interface {
Sync,
}

fn main() -> DeltaResult<()> {
fn main() -> ExitCode {
env_logger::init();
match try_main() {
Ok(()) => ExitCode::SUCCESS,
Err(e) => {
println!("{e:#?}");
ExitCode::FAILURE
}
}
}

fn try_main() -> DeltaResult<()> {
let cli = Cli::parse();
let url = url::Url::parse(&cli.path)?;

Expand Down
65 changes: 58 additions & 7 deletions kernel/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
use std::{num::ParseIntError, string::FromUtf8Error};
use std::{
backtrace::{Backtrace, BacktraceStatus},
num::ParseIntError,
string::FromUtf8Error,
};

use crate::schema::DataType;

pub type DeltaResult<T, E = Error> = std::result::Result<T, E>;

#[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<Self>,
backtrace: Box<Backtrace>,
},

#[cfg(any(feature = "default-client", feature = "sync-client"))]
#[error("Arrow error: {0}")]
Arrow(#[from] arrow_schema::ArrowError),
#[error(transparent)]
Arrow(arrow_schema::ArrowError),

#[error("Invalid engine data type. Could not convert to {0}")]
EngineDataType(String),
Expand All @@ -25,8 +39,8 @@ pub enum Error {
source: Box<dyn std::error::Error + Send + Sync + 'static>,
},

#[error("IO error: {0}")]
IOError(#[from] std::io::Error),
#[error(transparent)]
IOError(std::io::Error),

#[cfg(feature = "parquet")]
#[error("Arrow error: {0}")]
Expand Down Expand Up @@ -63,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,
Expand Down Expand Up @@ -119,6 +133,43 @@ impl Error {
pub fn join_failure(msg: impl ToString) -> Self {
Self::JoinFailure(msg.to_string())
}

// Capture a backtrace when the error is constructed.
#[must_use]
pub fn with_backtrace(self) -> Self {
let backtrace = Backtrace::capture();
match backtrace.status() {
BacktraceStatus::Captured => Self::Backtraced {
source: Box::new(self),
backtrace: Box::new(backtrace),
},
_ => self,
}
}
}

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<arrow_schema::ArrowError> for Error {
fn from(value: arrow_schema::ArrowError) -> Self {
Self::Arrow(value).with_backtrace()
}
}

#[cfg(feature = "object_store")]
Expand Down

0 comments on commit 02acc9c

Please sign in to comment.