refactor: Refactor usage of BoxedError (#48)

* feat: Define a general boxed error

* refactor: common_function use Error in common_query

* feat: Add tests to define_opaque_error macro

* refactor: Refactor table and table engine error

* refactor: recordbatch remove arrow dev-dependency

* refactor: datanode crate use common_error::BoxedError

* chore: Fix clippy

* feat: Returning source status code when using BoxedError

* test: Fix opaque error test

* test: Add tests for table::Error & table_engine::Error

* test: Add test for RecordBatch::new()

* test: Remove generated tests from define_opaque_error

* chore: Address cr comment
This commit is contained in:
evenyag
2022-06-21 15:24:45 +08:00
committed by GitHub
parent 4071b0cff2
commit 6ec870625f
18 changed files with 268 additions and 191 deletions

View File

@@ -5,38 +5,39 @@ use common_error::prelude::*;
use datafusion_common::DataFusionError;
use datatypes::error::Error as DataTypeError;
common_error::define_opaque_error!(Error);
#[derive(Debug, Snafu)]
#[snafu(visibility(pub))]
pub enum Error {
pub enum InnerError {
#[snafu(display("Fail to execute function, source: {}", source))]
ExecuteFunction {
source: DataFusionError,
backtrace: Backtrace,
},
#[snafu(display("Fail to cast scalar value into vector: {}", source))]
FromScalarValue {
#[snafu(backtrace)]
source: DataTypeError,
},
#[snafu(display("Fail to cast arrow array into vector: {:?}, {}", data_type, source))]
IntoVector {
#[snafu(backtrace)]
source: DataTypeError,
data_type: ArrowDatatype,
},
#[snafu(display("External error: {}, {}", msg, backtrace))]
External { msg: String, backtrace: Backtrace },
}
pub type Result<T> = std::result::Result<T, Error>;
impl ErrorExt for Error {
impl ErrorExt for InnerError {
fn status_code(&self) -> StatusCode {
match self {
Error::ExecuteFunction { .. } => StatusCode::EngineExecuteQuery,
Error::IntoVector { source, .. } => source.status_code(),
Error::FromScalarValue { source } => source.status_code(),
Error::External { .. } => StatusCode::Internal,
InnerError::ExecuteFunction { .. } => StatusCode::EngineExecuteQuery,
InnerError::IntoVector { source, .. } => source.status_code(),
InnerError::FromScalarValue { source } => source.status_code(),
}
}
@@ -49,6 +50,12 @@ impl ErrorExt for Error {
}
}
impl From<InnerError> for Error {
fn from(e: InnerError) -> Error {
Error::new(e)
}
}
impl From<Error> for DataFusionError {
fn from(e: Error) -> DataFusionError {
DataFusionError::External(Box::new(e))
@@ -66,16 +73,18 @@ mod tests {
}
fn assert_error(err: &Error, code: StatusCode) {
assert_eq!(code, err.status_code());
assert!(err.backtrace_opt().is_some());
let inner_err = err.as_any().downcast_ref::<InnerError>().unwrap();
assert_eq!(code, inner_err.status_code());
assert!(inner_err.backtrace_opt().is_some());
}
#[test]
fn test_datafusion_as_source() {
let err = throw_df_error()
.context(ExecuteFunctionSnafu {})
let err: Error = throw_df_error()
.context(ExecuteFunctionSnafu)
.err()
.unwrap();
.unwrap()
.into();
assert_error(&err, StatusCode::EngineExecuteQuery);
}
@@ -88,12 +97,13 @@ mod tests {
#[test]
fn test_into_vector_error() {
let err = raise_datatype_error()
let err: Error = raise_datatype_error()
.context(IntoVectorSnafu {
data_type: ArrowDatatype::Int32,
})
.err()
.unwrap();
.unwrap()
.into();
assert!(err.backtrace_opt().is_some());
let datatype_err = raise_datatype_error().err().unwrap();
assert_eq!(datatype_err.status_code(), err.status_code());

View File

@@ -62,9 +62,9 @@ where
if len.is_some() {
result.map(ColumnarValue::Vector)
} else {
ScalarValue::try_from_array(&result?.to_arrow_array(), 0)
Ok(ScalarValue::try_from_array(&result?.to_arrow_array(), 0)
.map(ColumnarValue::Scalar)
.context(ExecuteFunctionSnafu)
.context(ExecuteFunctionSnafu)?)
}
})
}