mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-01-08 06:12:55 +00:00
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:
@@ -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(_)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user