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

@@ -83,101 +83,64 @@ macro_rules! define_opaque_error {
};
}
// Define a general boxed error.
define_opaque_error!(BoxedError);
#[cfg(test)]
mod tests {
use std::error::Error as StdError;
use std::error::Error;
use snafu::ErrorCompat;
use super::*;
use crate::prelude::*;
use crate::format::DebugFormat;
use crate::mock::MockError;
define_opaque_error!(Error);
#[test]
fn test_opaque_error_without_backtrace() {
let err = BoxedError::new(MockError::new(StatusCode::Internal));
assert!(err.backtrace_opt().is_none());
assert_eq!(StatusCode::Internal, err.status_code());
assert!(err.as_any().downcast_ref::<MockError>().is_some());
assert!(err.source().is_none());
#[derive(Debug, Snafu)]
enum InnerError {
#[snafu(display("This is a leaf error, val: {}", val))]
Leaf { val: i32, backtrace: Backtrace },
#[snafu(display("This is an internal error"))]
Internal {
source: std::io::Error,
backtrace: Backtrace,
},
}
impl ErrorExt for InnerError {
fn status_code(&self) -> StatusCode {
StatusCode::Internal
}
fn backtrace_opt(&self) -> Option<&snafu::Backtrace> {
ErrorCompat::backtrace(self)
}
fn as_any(&self) -> &dyn Any {
self
}
}
impl From<InnerError> for Error {
fn from(err: InnerError) -> Self {
Self::new(err)
}
}
fn throw_leaf() -> std::result::Result<(), InnerError> {
LeafSnafu { val: 10 }.fail()
}
fn throw_io() -> std::result::Result<(), std::io::Error> {
Err(std::io::Error::new(std::io::ErrorKind::Other, "oh no!"))
}
fn throw_internal() -> std::result::Result<(), InnerError> {
throw_io().context(InternalSnafu)
assert!(ErrorCompat::backtrace(&err).is_none());
}
#[test]
fn test_inner_error() {
let leaf = throw_leaf().err().unwrap();
assert!(leaf.backtrace_opt().is_some());
assert!(leaf.source().is_none());
fn test_opaque_error_with_backtrace() {
let err = BoxedError::new(MockError::with_backtrace(StatusCode::Internal));
assert!(err.backtrace_opt().is_some());
assert_eq!(StatusCode::Internal, err.status_code());
assert!(err.as_any().downcast_ref::<MockError>().is_some());
assert!(err.source().is_none());
let internal = throw_internal().err().unwrap();
assert!(internal.backtrace_opt().is_some());
assert!(internal.source().is_some());
}
assert!(ErrorCompat::backtrace(&err).is_some());
#[test]
fn test_opaque_error() {
// Test leaf error.
let err: Error = throw_leaf().map_err(Into::into).err().unwrap();
let msg = format!("{:?}", err);
assert!(msg.contains("\nBacktrace:\n"));
let fmt_msg = format!("{:?}", DebugFormat::new(&err));
assert_eq!(msg, fmt_msg);
assert!(ErrorCompat::backtrace(&err).is_some());
let msg = err.to_string();
msg.contains("Internal");
}
#[test]
fn test_opaque_error_with_source() {
let leaf_err = MockError::with_backtrace(StatusCode::Internal);
let internal_err = MockError::with_source(leaf_err);
let err = BoxedError::new(internal_err);
assert!(err.backtrace_opt().is_some());
assert_eq!("This is a leaf error, val: 10", err.to_string());
assert_eq!(StatusCode::Internal, err.status_code());
assert!(err.as_any().downcast_ref::<MockError>().is_some());
assert!(err.source().is_some());
err.as_any().downcast_ref::<InnerError>().unwrap();
// Test internal error.
let err: Error = throw_internal().map_err(Into::into).err().unwrap();
let msg = format!("{:?}", err);
assert!(msg.contains("\nBacktrace:\n"));
assert!(msg.contains("Caused by"));
let fmt_msg = format!("{:?}", DebugFormat::new(&err));
assert_eq!(msg, fmt_msg);
assert!(ErrorCompat::backtrace(&err).is_some());
assert!(err.backtrace_opt().is_some());
assert_eq!("This is an internal error", err.to_string());
assert_eq!(StatusCode::Internal, err.status_code());
err.as_any().downcast_ref::<InnerError>().unwrap();
}
}

View File

@@ -6,7 +6,7 @@ pub mod status_code;
pub mod prelude {
pub use snafu::{prelude::*, Backtrace, ErrorCompat};
pub use crate::ext::ErrorExt;
pub use crate::ext::{BoxedError, ErrorExt};
pub use crate::format::DebugFormat;
pub use crate::status_code::StatusCode;
}