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

@@ -1,7 +1,9 @@
use std::any::Any;
use common_error::prelude::*;
use common_recordbatch::error::Error as RecordBatchError;
use datafusion::error::DataFusionError;
use datatypes::arrow::error::ArrowError;
common_error::define_opaque_error!(Error);
@@ -23,14 +25,30 @@ pub enum InnerError {
backtrace: Backtrace,
},
#[snafu(display("Missing column when insert, column : {}", name))]
#[snafu(display("Missing column when insert, column: {}", name))]
MissingColumn { name: String, backtrace: Backtrace },
#[snafu(display("Not expected to run ExecutionPlan more than once"))]
ExecuteRepeatedly { backtrace: Backtrace },
#[snafu(display("Poll stream failed, source: {}", source))]
PollStream {
source: ArrowError,
backtrace: Backtrace,
},
}
impl ErrorExt for InnerError {
fn status_code(&self) -> StatusCode {
match self {
InnerError::Datafusion { .. } | InnerError::PollStream { .. } => {
StatusCode::EngineExecuteQuery
}
InnerError::MissingColumn { .. } => StatusCode::InvalidArguments,
InnerError::ExecuteRepeatedly { .. } => StatusCode::Unexpected,
}
}
fn backtrace_opt(&self) -> Option<&Backtrace> {
ErrorCompat::backtrace(self)
}
@@ -52,6 +70,12 @@ impl From<InnerError> for DataFusionError {
}
}
impl From<InnerError> for RecordBatchError {
fn from(e: InnerError) -> RecordBatchError {
RecordBatchError::new(e)
}
}
#[cfg(test)]
mod tests {
use super::*;
@@ -64,14 +88,49 @@ mod tests {
ExecuteRepeatedlySnafu {}.fail()?
}
fn throw_missing_column_inner() -> std::result::Result<(), InnerError> {
MissingColumnSnafu { name: "test" }.fail()
}
fn throw_missing_column() -> Result<()> {
Ok(throw_missing_column_inner()?)
}
fn throw_arrow() -> Result<()> {
Err(ArrowError::Overflow).context(PollStreamSnafu)?
}
#[test]
fn test_error() {
let err = throw_df_error().err().unwrap();
assert!(err.backtrace_opt().is_some());
assert_eq!(StatusCode::Unknown, err.status_code());
assert_eq!(StatusCode::EngineExecuteQuery, err.status_code());
let err = throw_repeatedly().err().unwrap();
assert!(err.backtrace_opt().is_some());
assert_eq!(StatusCode::Unknown, err.status_code());
assert_eq!(StatusCode::Unexpected, err.status_code());
let err = throw_missing_column().err().unwrap();
assert!(err.backtrace_opt().is_some());
assert_eq!(StatusCode::InvalidArguments, err.status_code());
let err = throw_arrow().err().unwrap();
assert!(err.backtrace_opt().is_some());
assert_eq!(StatusCode::EngineExecuteQuery, err.status_code());
}
#[test]
fn test_into_record_batch_error() {
let err = throw_missing_column_inner().err().unwrap();
let err: RecordBatchError = err.into();
assert!(err.backtrace_opt().is_some());
assert_eq!(StatusCode::InvalidArguments, err.status_code());
}
#[test]
fn test_into_df_error() {
let err = throw_missing_column_inner().err().unwrap();
let err: DataFusionError = err.into();
assert!(matches!(err, DataFusionError::External(_)));
}
}

View File

@@ -7,7 +7,7 @@ use std::mem;
use std::sync::{Arc, Mutex};
use common_query::logical_plan::Expr;
use common_recordbatch::error::{self as recordbatch_error, Result as RecordBatchResult};
use common_recordbatch::error::Result as RecordBatchResult;
use common_recordbatch::{RecordBatch, RecordBatchStream, SendableRecordBatchStream};
use datafusion::arrow::datatypes::SchemaRef as DfSchemaRef;
/// Datafusion table adpaters
@@ -297,7 +297,7 @@ impl Stream for RecordBatchStreamAdapter {
Poll::Pending => Poll::Pending,
Poll::Ready(Some(df_recordbatch)) => Poll::Ready(Some(Ok(RecordBatch {
schema: self.schema(),
df_recordbatch: df_recordbatch.context(recordbatch_error::ArrowSnafu)?,
df_recordbatch: df_recordbatch.context(error::PollStreamSnafu)?,
}))),
Poll::Ready(None) => Poll::Ready(None),
}