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

@@ -4,6 +4,7 @@ use std::sync::Arc;
use std::sync::RwLock;
use async_trait::async_trait;
use common_error::ext::BoxedError;
use snafu::ResultExt;
use store_api::storage::ConcreteDataType;
use store_api::storage::{
@@ -18,7 +19,7 @@ use table::{
table::TableRef,
};
use crate::error::{CreateTableSnafu, Error, Result};
use crate::error::{self, Error, Result};
use crate::table::MitoTable;
pub const DEFAULT_ENGINE: &str = "mito";
@@ -150,8 +151,8 @@ impl<Store: StorageEngine> MitoEngineInner<Store> {
},
)
.await
.map_err(|e| Box::new(e) as _)
.context(CreateTableSnafu)?;
.map_err(BoxedError::new)
.context(error::CreateRegionSnafu)?;
// Use region meta schema instead of request schema
let table_meta = TableMetaBuilder::new(region.in_memory_metadata().schema().clone())

View File

@@ -1,17 +1,15 @@
use std::any::Any;
use common_error::ext::BoxedError;
use common_error::prelude::*;
// TODO(dennis): use ErrorExt instead.
pub type BoxedError = Box<dyn std::error::Error + Send + Sync>;
#[derive(Debug, Snafu)]
#[snafu(visibility(pub))]
pub enum Error {
#[snafu(display("Fail to create table, source: {}", source))]
CreateTable {
#[snafu(display("Fail to create region, source: {}", source))]
CreateRegion {
#[snafu(backtrace)]
source: BoxedError,
backtrace: Backtrace,
},
}
@@ -20,8 +18,7 @@ pub type Result<T> = std::result::Result<T, Error>;
impl ErrorExt for Error {
fn status_code(&self) -> StatusCode {
match self {
//TODO: should return the source's status code after use ErrorExt in BoxedError.
Error::CreateTable { .. } => StatusCode::InvalidArguments,
Error::CreateRegion { source, .. } => source.status_code(),
}
}
@@ -33,3 +30,25 @@ impl ErrorExt for Error {
self
}
}
#[cfg(test)]
mod tests {
use common_error::ext::BoxedError;
use common_error::mock::MockError;
use super::*;
fn throw_create_table(code: StatusCode) -> Result<()> {
let mock_err = MockError::with_backtrace(code);
Err(BoxedError::new(mock_err)).context(CreateRegionSnafu)
}
#[test]
fn test_error() {
let err = throw_create_table(StatusCode::InvalidArguments)
.err()
.unwrap();
assert_eq!(StatusCode::InvalidArguments, err.status_code());
assert!(err.backtrace_opt().is_some());
}
}

View File

@@ -1,20 +1,18 @@
#[cfg(test)]
pub mod test;
use std::any::Any;
use std::pin::Pin;
use async_trait::async_trait;
use common_query::logical_plan::Expr;
use common_recordbatch::error::{Result as RecordBatchResult, StorageSnafu};
use common_recordbatch::error::{Error as RecordBatchError, Result as RecordBatchResult};
use common_recordbatch::{RecordBatch, RecordBatchStream, SendableRecordBatchStream};
use datafusion_common::record_batch::RecordBatch as DfRecordBatch;
use futures::task::{Context, Poll};
use futures::Stream;
use snafu::OptionExt;
use snafu::ResultExt;
use store_api::storage::SchemaRef;
use store_api::storage::{
ChunkReader, PutOperation, ReadContext, Region, ScanRequest, Snapshot, WriteContext,
ChunkReader, PutOperation, ReadContext, Region, ScanRequest, SchemaRef, Snapshot, WriteContext,
WriteRequest,
};
use table::error::{Error as TableError, MissingColumnSnafu, Result as TableResult};
@@ -110,27 +108,9 @@ impl<R: Region> Table for MitoTable<R> {
for chunk in reader.next_chunk()
.await
.map_err(|e| Box::new(e) as _)
.context(StorageSnafu {
msg: "Fail to reader chunk",
})?
.map_err(RecordBatchError::new)?
{
let batch = DfRecordBatch::try_new(
stream_schema.arrow_schema().clone(),
chunk.columns
.into_iter()
.map(|v| v.to_arrow_array())
.collect());
let batch = batch
.map_err(|e| Box::new(e) as _)
.context(StorageSnafu {
msg: "Fail to new datafusion record batch",
})?;
yield RecordBatch {
schema: stream_schema.clone(),
df_recordbatch: batch,
}
yield RecordBatch::new(stream_schema.clone(), chunk.columns)?
}
});