diff --git a/src/api/src/error.rs b/src/api/src/error.rs index 034f856158..d5f6f091e3 100644 --- a/src/api/src/error.rs +++ b/src/api/src/error.rs @@ -18,7 +18,7 @@ use common_error::ext::ErrorExt; use common_error::prelude::StatusCode; use datatypes::prelude::ConcreteDataType; use snafu::prelude::*; -use snafu::{Backtrace, ErrorCompat}; +use snafu::Location; pub type Result = std::result::Result; @@ -26,12 +26,12 @@ pub type Result = std::result::Result; #[snafu(visibility(pub))] pub enum Error { #[snafu(display("Unknown proto column datatype: {}", datatype))] - UnknownColumnDataType { datatype: i32, backtrace: Backtrace }, + UnknownColumnDataType { datatype: i32, location: Location }, #[snafu(display("Failed to create column datatype from {:?}", from))] IntoColumnDataType { from: ConcreteDataType, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -66,9 +66,6 @@ impl ErrorExt for Error { | Error::InvalidColumnDefaultConstraint { source, .. } => source.status_code(), } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } fn as_any(&self) -> &dyn Any { self diff --git a/src/catalog/src/error.rs b/src/catalog/src/error.rs index 48dcd06eec..c9c46f2068 100644 --- a/src/catalog/src/error.rs +++ b/src/catalog/src/error.rs @@ -19,7 +19,7 @@ use common_error::ext::{BoxedError, ErrorExt}; use common_error::prelude::{Snafu, StatusCode}; use datafusion::error::DataFusionError; use datatypes::prelude::ConcreteDataType; -use snafu::{Backtrace, ErrorCompat}; +use snafu::Location; use crate::DeregisterTableRequest; @@ -50,7 +50,7 @@ pub enum Error { }, #[snafu(display("System catalog is not valid: {}", msg))] - SystemCatalog { msg: String, backtrace: Backtrace }, + SystemCatalog { msg: String, location: Location }, #[snafu(display( "System catalog table type mismatch, expected: binary, found: {:?}", @@ -58,28 +58,28 @@ pub enum Error { ))] SystemCatalogTypeMismatch { data_type: ConcreteDataType, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Invalid system catalog entry type: {:?}", entry_type))] InvalidEntryType { entry_type: Option, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Invalid system catalog key: {:?}", key))] InvalidKey { key: Option, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Catalog value is not present"))] - EmptyValue { backtrace: Backtrace }, + EmptyValue { location: Location }, #[snafu(display("Failed to deserialize value, source: {}", source))] ValueDeserialize { source: serde_json::error::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Table engine not found: {}, source: {}", engine_name, source))] @@ -92,32 +92,29 @@ pub enum Error { #[snafu(display("Cannot find catalog by name: {}", catalog_name))] CatalogNotFound { catalog_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Cannot find schema {} in catalog {}", schema, catalog))] SchemaNotFound { catalog: String, schema: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Table `{}` already exists", table))] - TableExists { table: String, backtrace: Backtrace }, + TableExists { table: String, location: Location }, #[snafu(display("Table `{}` not exist", table))] - TableNotExist { table: String, backtrace: Backtrace }, + TableNotExist { table: String, location: Location }, #[snafu(display("Schema {} already exists", schema))] - SchemaExists { - schema: String, - backtrace: Backtrace, - }, + SchemaExists { schema: String, location: Location }, #[snafu(display("Operation {} not implemented yet", operation))] Unimplemented { operation: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to open table, table info: {}, source: {}", table_info, source))] @@ -130,7 +127,7 @@ pub enum Error { #[snafu(display("Table not found while opening table, table info: {}", table_info))] TableNotFound { table_info: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to read system catalog table records"))] @@ -160,7 +157,7 @@ pub enum Error { }, #[snafu(display("Illegal catalog manager state: {}", msg))] - IllegalManagerState { backtrace: Backtrace, msg: String }, + IllegalManagerState { location: Location, msg: String }, #[snafu(display("Failed to scan system catalog table, source: {}", source))] SystemCatalogTableScan { @@ -228,10 +225,7 @@ pub enum Error { }, #[snafu(display("Invalid system table definition: {err_msg}"))] - InvalidSystemTableDef { - err_msg: String, - backtrace: Backtrace, - }, + InvalidSystemTableDef { err_msg: String, location: Location }, } pub type Result = std::result::Result; @@ -285,10 +279,6 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } @@ -312,7 +302,7 @@ mod tests { StatusCode::TableAlreadyExists, Error::TableExists { table: "some_table".to_string(), - backtrace: Backtrace::generate(), + location: Location::generate(), } .status_code() ); @@ -326,7 +316,7 @@ mod tests { StatusCode::StorageUnavailable, Error::SystemCatalog { msg: "".to_string(), - backtrace: Backtrace::generate(), + location: Location::generate(), } .status_code() ); @@ -335,7 +325,7 @@ mod tests { StatusCode::Internal, Error::SystemCatalogTypeMismatch { data_type: ConcreteDataType::binary_datatype(), - backtrace: Backtrace::generate(), + location: Location::generate(), } .status_code() ); @@ -349,7 +339,7 @@ mod tests { pub fn test_errors_to_datafusion_error() { let e: DataFusionError = Error::TableExists { table: "test_table".to_string(), - backtrace: Backtrace::generate(), + location: Location::generate(), } .into(); match e { diff --git a/src/catalog/src/local/memory.rs b/src/catalog/src/local/memory.rs index fcee7c9a3c..7c486c2fd9 100644 --- a/src/catalog/src/local/memory.rs +++ b/src/catalog/src/local/memory.rs @@ -396,7 +396,6 @@ mod tests { let other_table = NumbersTable::new(12); let result = provider.register_table(table_name.to_string(), Arc::new(other_table)); let err = result.err().unwrap(); - assert!(err.backtrace_opt().is_some()); assert_eq!(StatusCode::TableAlreadyExists, err.status_code()); } diff --git a/src/client/src/error.rs b/src/client/src/error.rs index a5c1878d6d..51608d7115 100644 --- a/src/client/src/error.rs +++ b/src/client/src/error.rs @@ -16,16 +16,14 @@ use std::any::Any; use std::str::FromStr; use common_error::prelude::*; +use snafu::Location; use tonic::{Code, Status}; #[derive(Debug, Snafu)] #[snafu(visibility(pub))] pub enum Error { #[snafu(display("Illegal Flight messages, reason: {}", reason))] - IllegalFlightMessages { - reason: String, - backtrace: Backtrace, - }, + IllegalFlightMessages { reason: String, location: Location }, #[snafu(display("Failed to do Flight get, code: {}, source: {}", tonic_code, source))] FlightGet { @@ -47,13 +45,10 @@ pub enum Error { }, #[snafu(display("Illegal GRPC client state: {}", err_msg))] - IllegalGrpcClientState { - err_msg: String, - backtrace: Backtrace, - }, + IllegalGrpcClientState { err_msg: String, location: Location }, #[snafu(display("Missing required field in protobuf, field: {}", field))] - MissingField { field: String, backtrace: Backtrace }, + MissingField { field: String, location: Location }, #[snafu(display( "Failed to create gRPC channel, peer address: {}, source: {}", @@ -93,10 +88,6 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } diff --git a/src/cmd/src/error.rs b/src/cmd/src/error.rs index 52a2c5c779..f680a33c7e 100644 --- a/src/cmd/src/error.rs +++ b/src/cmd/src/error.rs @@ -16,6 +16,7 @@ use std::any::Any; use common_error::prelude::*; use rustyline::error::ReadlineError; +use snafu::Location; #[derive(Debug, Snafu)] #[snafu(visibility(pub))] @@ -66,20 +67,20 @@ pub enum Error { ReadConfig { path: String, source: std::io::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to parse config, source: {}", source))] ParseConfig { source: toml::de::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Missing config, msg: {}", msg))] - MissingConfig { msg: String, backtrace: Backtrace }, + MissingConfig { msg: String, location: Location }, #[snafu(display("Illegal config: {}", msg))] - IllegalConfig { msg: String, backtrace: Backtrace }, + IllegalConfig { msg: String, location: Location }, #[snafu(display("Illegal auth config: {}", source))] IllegalAuthConfig { @@ -100,13 +101,13 @@ pub enum Error { #[snafu(display("Cannot create REPL: {}", source))] ReplCreation { source: ReadlineError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Error reading command: {}", source))] Readline { source: ReadlineError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to request database, sql: {sql}, source: {source}"))] @@ -187,78 +188,7 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } } - -#[cfg(test)] -mod tests { - use super::*; - - type StdResult = std::result::Result<(), E>; - - #[test] - fn test_start_node_error() { - fn throw_datanode_error() -> StdResult { - datanode::error::MissingNodeIdSnafu {}.fail() - } - - let e = throw_datanode_error() - .context(StartDatanodeSnafu) - .err() - .unwrap(); - - assert!(e.backtrace_opt().is_some()); - assert_eq!(e.status_code(), StatusCode::InvalidArguments); - } - - #[test] - fn test_start_frontend_error() { - fn throw_frontend_error() -> StdResult { - frontend::error::InvalidSqlSnafu { err_msg: "failed" }.fail() - } - - let e = throw_frontend_error() - .context(StartFrontendSnafu) - .err() - .unwrap(); - - assert!(e.backtrace_opt().is_some()); - assert_eq!(e.status_code(), StatusCode::InvalidArguments); - } - - #[test] - fn test_start_metasrv_error() { - fn throw_metasrv_error() -> StdResult { - meta_srv::error::StreamNoneSnafu {}.fail() - } - - let e = throw_metasrv_error() - .context(StartMetaServerSnafu) - .err() - .unwrap(); - - assert!(e.backtrace_opt().is_some()); - assert_eq!(e.status_code(), StatusCode::Internal); - } - - #[test] - fn test_read_config_error() { - fn throw_read_config_error() -> StdResult { - Err(std::io::ErrorKind::NotFound.into()) - } - - let e = throw_read_config_error() - .context(ReadConfigSnafu { path: "test" }) - .err() - .unwrap(); - - assert!(e.backtrace_opt().is_some()); - assert_eq!(e.status_code(), StatusCode::InvalidArguments); - } -} diff --git a/src/common/base/src/buffer.rs b/src/common/base/src/buffer.rs index 3d4de246b6..430157a62a 100644 --- a/src/common/base/src/buffer.rs +++ b/src/common/base/src/buffer.rs @@ -18,7 +18,7 @@ use std::io::{Read, Write}; use bytes::{Buf, BufMut, BytesMut}; use common_error::prelude::ErrorExt; use paste::paste; -use snafu::{ensure, Backtrace, ErrorCompat, ResultExt, Snafu}; +use snafu::{ensure, Location, ResultExt, Snafu}; #[derive(Debug, Snafu)] #[snafu(visibility(pub))] @@ -31,29 +31,33 @@ pub enum Error { Overflow { src_len: usize, dst_len: usize, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Buffer underflow"))] - Underflow { backtrace: Backtrace }, + Underflow { location: Location }, #[snafu(display("IO operation reach EOF, source: {}", source))] Eof { source: std::io::Error, - backtrace: Backtrace, + location: Location, }, } pub type Result = std::result::Result; impl ErrorExt for Error { - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } + + fn location_opt(&self) -> Option { + match self { + Error::Overflow { location, .. } => Some(*location), + Error::Underflow { location, .. } => Some(*location), + Error::Eof { location, .. } => Some(*location), + } + } } macro_rules! impl_read_le { diff --git a/src/common/catalog/src/error.rs b/src/common/catalog/src/error.rs index a3fc0133a5..3ab98ebf32 100644 --- a/src/common/catalog/src/error.rs +++ b/src/common/catalog/src/error.rs @@ -16,29 +16,29 @@ use std::any::Any; use common_error::ext::ErrorExt; use common_error::prelude::{Snafu, StatusCode}; -use snafu::{Backtrace, ErrorCompat}; +use snafu::Location; #[derive(Debug, Snafu)] #[snafu(visibility(pub))] pub enum Error { #[snafu(display("Invalid catalog info: {}", key))] - InvalidCatalog { key: String, backtrace: Backtrace }, + InvalidCatalog { key: String, location: Location }, #[snafu(display("Failed to deserialize catalog entry value: {}", raw))] DeserializeCatalogEntryValue { raw: String, - backtrace: Backtrace, + location: Location, source: serde_json::error::Error, }, #[snafu(display("Failed to serialize catalog entry value"))] SerializeCatalogEntryValue { - backtrace: Backtrace, + location: Location, source: serde_json::error::Error, }, #[snafu(display("Failed to parse node id: {}", key))] - ParseNodeId { key: String, backtrace: Backtrace }, + ParseNodeId { key: String, location: Location }, } impl ErrorExt for Error { @@ -51,10 +51,6 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } diff --git a/src/common/datasource/src/error.rs b/src/common/datasource/src/error.rs index d24103daba..657a536098 100644 --- a/src/common/datasource/src/error.rs +++ b/src/common/datasource/src/error.rs @@ -15,6 +15,7 @@ use std::any::Any; use common_error::prelude::*; +use snafu::Location; use url::ParseError; #[derive(Debug, Snafu)] @@ -35,13 +36,13 @@ pub enum Error { #[snafu(display("Failed to build backend, source: {}", source))] BuildBackend { source: object_store::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to list object in path: {}, source: {}", path, source))] ListObjects { path: String, - backtrace: Backtrace, + location: Location, source: object_store::Error, }, @@ -65,11 +66,19 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } + + fn location_opt(&self) -> Option { + match self { + Error::BuildBackend { location, .. } => Some(*location), + Error::ListObjects { location, .. } => Some(*location), + Error::UnsupportedBackendProtocol { .. } + | Error::EmptyHostPath { .. } + | Error::InvalidPath { .. } + | Error::InvalidUrl { .. } + | Error::InvalidConnection { .. } => None, + } + } } diff --git a/src/common/error/src/ext.rs b/src/common/error/src/ext.rs index 371c3434da..261f8f7736 100644 --- a/src/common/error/src/ext.rs +++ b/src/common/error/src/ext.rs @@ -23,10 +23,12 @@ pub trait ErrorExt: std::error::Error { StatusCode::Unknown } - /// Get the reference to the backtrace of this error, None if the backtrace is unavailable. - // Add `_opt` suffix to avoid confusing with similar method in `std::error::Error`, once backtrace - // in std is stable, we can deprecate this method. - fn backtrace_opt(&self) -> Option<&crate::snafu::Backtrace>; + // TODO(ruihang): remove this default implementation + /// Get the location of this error, None if the location is unavailable. + /// Add `_opt` suffix to avoid confusing with similar method in `std::error::Error` + fn location_opt(&self) -> Option { + None + } /// Returns the error as [Any](std::any::Any) so that it can be /// downcast to a specific implementation. @@ -71,8 +73,8 @@ impl crate::ext::ErrorExt for BoxedError { self.inner.status_code() } - fn backtrace_opt(&self) -> Option<&crate::snafu::Backtrace> { - self.inner.backtrace_opt() + fn location_opt(&self) -> Option { + self.inner.location_opt() } fn as_any(&self) -> &dyn std::any::Any { @@ -84,7 +86,7 @@ impl crate::ext::ErrorExt for BoxedError { // via `ErrorCompat::backtrace()`. impl crate::snafu::ErrorCompat for BoxedError { fn backtrace(&self) -> Option<&crate::snafu::Backtrace> { - self.inner.backtrace_opt() + None } } @@ -118,7 +120,7 @@ impl crate::ext::ErrorExt for PlainError { self.status_code } - fn backtrace_opt(&self) -> Option<&crate::snafu::Backtrace> { + fn location_opt(&self) -> Option { None } @@ -126,62 +128,3 @@ impl crate::ext::ErrorExt for PlainError { self as _ } } - -#[cfg(test)] -mod tests { - use std::error::Error; - - use snafu::ErrorCompat; - - use super::*; - use crate::format::DebugFormat; - use crate::mock::MockError; - - #[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::().is_some()); - assert!(err.source().is_none()); - - assert!(ErrorCompat::backtrace(&err).is_none()); - } - - #[test] - 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::().is_some()); - assert!(err.source().is_none()); - - assert!(ErrorCompat::backtrace(&err).is_some()); - - let msg = format!("{err:?}"); - assert!(msg.contains("\nBacktrace:\n")); - let fmt_msg = format!("{:?}", DebugFormat::new(&err)); - assert_eq!(msg, fmt_msg); - - 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!(StatusCode::Internal, err.status_code()); - assert!(err.as_any().downcast_ref::().is_some()); - assert!(err.source().is_some()); - - let msg = format!("{err:?}"); - assert!(msg.contains("\nBacktrace:\n")); - assert!(msg.contains("Caused by")); - - assert!(ErrorCompat::backtrace(&err).is_some()); - } -} diff --git a/src/common/error/src/format.rs b/src/common/error/src/format.rs index 96816a2b3e..9bf2196409 100644 --- a/src/common/error/src/format.rs +++ b/src/common/error/src/format.rs @@ -33,9 +33,9 @@ impl<'a, E: ErrorExt + ?Sized> fmt::Debug for DebugFormat<'a, E> { // Source error use debug format for more verbose info. write!(f, " Caused by: {source:?}")?; } - if let Some(backtrace) = self.0.backtrace_opt() { + if let Some(location) = self.0.location_opt() { // Add a newline to separate causes and backtrace. - write!(f, "\nBacktrace:\n{backtrace}")?; + write!(f, " at: {location}")?; } Ok(()) @@ -47,7 +47,7 @@ mod tests { use std::any::Any; use snafu::prelude::*; - use snafu::{Backtrace, GenerateImplicitData}; + use snafu::{GenerateImplicitData, Location}; use super::*; @@ -56,7 +56,7 @@ mod tests { struct Leaf; impl ErrorExt for Leaf { - fn backtrace_opt(&self) -> Option<&Backtrace> { + fn location_opt(&self) -> Option { None } @@ -66,14 +66,14 @@ mod tests { } #[derive(Debug, Snafu)] - #[snafu(display("This is a leaf with backtrace"))] - struct LeafWithBacktrace { - backtrace: Backtrace, + #[snafu(display("This is a leaf with location"))] + struct LeafWithLocation { + location: Location, } - impl ErrorExt for LeafWithBacktrace { - fn backtrace_opt(&self) -> Option<&Backtrace> { - Some(&self.backtrace) + impl ErrorExt for LeafWithLocation { + fn location_opt(&self) -> Option { + None } fn as_any(&self) -> &dyn Any { @@ -86,12 +86,12 @@ mod tests { struct Internal { #[snafu(source)] source: Leaf, - backtrace: Backtrace, + location: Location, } impl ErrorExt for Internal { - fn backtrace_opt(&self) -> Option<&Backtrace> { - Some(&self.backtrace) + fn location_opt(&self) -> Option { + None } fn as_any(&self) -> &dyn Any { @@ -106,19 +106,21 @@ mod tests { let msg = format!("{:?}", DebugFormat::new(&err)); assert_eq!("This is a leaf error.", msg); - let err = LeafWithBacktrace { - backtrace: Backtrace::generate(), + let err = LeafWithLocation { + location: Location::generate(), }; + // TODO(ruihang): display location here let msg = format!("{:?}", DebugFormat::new(&err)); - assert!(msg.starts_with("This is a leaf with backtrace.\nBacktrace:\n")); + assert!(msg.starts_with("This is a leaf with location.")); let err = Internal { source: Leaf, - backtrace: Backtrace::generate(), + location: Location::generate(), }; + // TODO(ruihang): display location here let msg = format!("{:?}", DebugFormat::new(&err)); - assert!(msg.contains("Internal error. Caused by: Leaf\nBacktrace:\n")); + assert!(msg.contains("Internal error. Caused by: Leaf")); } } diff --git a/src/common/error/src/mock.rs b/src/common/error/src/mock.rs index 281c386f84..27b2471045 100644 --- a/src/common/error/src/mock.rs +++ b/src/common/error/src/mock.rs @@ -17,7 +17,7 @@ use std::any::Any; use std::fmt; -use snafu::GenerateImplicitData; +use snafu::Location; use crate::prelude::*; @@ -25,34 +25,19 @@ use crate::prelude::*; #[derive(Debug)] pub struct MockError { pub code: StatusCode, - backtrace: Option, source: Option>, } impl MockError { /// Create a new [MockError] without backtrace. pub fn new(code: StatusCode) -> MockError { - MockError { - code, - backtrace: None, - source: None, - } - } - - /// Create a new [MockError] with backtrace. - pub fn with_backtrace(code: StatusCode) -> MockError { - MockError { - code, - backtrace: Some(Backtrace::generate()), - source: None, - } + MockError { code, source: None } } /// Create a new [MockError] with source. pub fn with_source(source: MockError) -> MockError { MockError { code: source.code, - backtrace: None, source: Some(Box::new(source)), } } @@ -75,39 +60,11 @@ impl ErrorExt for MockError { self.code } - fn backtrace_opt(&self) -> Option<&Backtrace> { - self.backtrace - .as_ref() - .or_else(|| self.source.as_ref().and_then(|err| err.backtrace_opt())) + fn location_opt(&self) -> Option { + None } fn as_any(&self) -> &dyn Any { self } } - -impl ErrorCompat for MockError { - fn backtrace(&self) -> Option<&Backtrace> { - self.backtrace_opt() - } -} - -#[cfg(test)] -mod tests { - use std::error::Error; - - use super::*; - - #[test] - fn test_mock_error() { - let err = MockError::new(StatusCode::Unknown); - assert!(err.backtrace_opt().is_none()); - - let err = MockError::with_backtrace(StatusCode::Unknown); - assert!(err.backtrace_opt().is_some()); - - let root_err = MockError::with_source(err); - assert!(root_err.source().is_some()); - assert!(root_err.backtrace_opt().is_some()); - } -} diff --git a/src/common/grpc-expr/src/error.rs b/src/common/grpc-expr/src/error.rs index 7cbb39bb26..07e2c42723 100644 --- a/src/common/grpc-expr/src/error.rs +++ b/src/common/grpc-expr/src/error.rs @@ -17,7 +17,7 @@ use std::any::Any; use api::DecodeError; use common_error::ext::ErrorExt; use common_error::prelude::{Snafu, StatusCode}; -use snafu::{Backtrace, ErrorCompat}; +use snafu::Location; #[derive(Debug, Snafu)] #[snafu(visibility(pub))] @@ -32,7 +32,7 @@ pub enum Error { DecodeInsert { source: DecodeError }, #[snafu(display("Illegal insert data"))] - IllegalInsertData { backtrace: Backtrace }, + IllegalInsertData { location: Location }, #[snafu(display("Column datatype error, source: {}", source))] ColumnDataType { @@ -48,17 +48,14 @@ pub enum Error { DuplicatedTimestampColumn { exists: String, duplicated: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Missing timestamp column, msg: {}", msg))] - MissingTimestampColumn { msg: String, backtrace: Backtrace }, + MissingTimestampColumn { msg: String, location: Location }, #[snafu(display("Invalid column proto: {}", err_msg))] - InvalidColumnProto { - err_msg: String, - backtrace: Backtrace, - }, + InvalidColumnProto { err_msg: String, location: Location }, #[snafu(display("Failed to create vector, source: {}", source))] CreateVector { #[snafu(backtrace)] @@ -66,7 +63,7 @@ pub enum Error { }, #[snafu(display("Missing required field in protobuf, field: {}", field))] - MissingField { field: String, backtrace: Backtrace }, + MissingField { field: String, location: Location }, #[snafu(display("Invalid column default constraint, source: {}", source))] ColumnDefaultConstraint { @@ -113,9 +110,6 @@ impl ErrorExt for Error { Error::UnrecognizedTableOption { .. } => StatusCode::InvalidArguments, } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } fn as_any(&self) -> &dyn Any { self diff --git a/src/common/grpc/src/error.rs b/src/common/grpc/src/error.rs index df408371e1..684fee57fc 100644 --- a/src/common/grpc/src/error.rs +++ b/src/common/grpc/src/error.rs @@ -16,7 +16,7 @@ use std::any::Any; use std::io; use common_error::prelude::{ErrorExt, StatusCode}; -use snafu::{Backtrace, ErrorCompat, Snafu}; +use snafu::{Location, Snafu}; pub type Result = std::result::Result; @@ -29,11 +29,11 @@ pub enum Error { #[snafu(display("Invalid config file path, {}", source))] InvalidConfigFilePath { source: io::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Missing required field in protobuf, field: {}", field))] - MissingField { field: String, backtrace: Backtrace }, + MissingField { field: String, location: Location }, #[snafu(display( "Write type mismatch, column name: {}, expected: {}, actual: {}", @@ -45,13 +45,13 @@ pub enum Error { column_name: String, expected: String, actual: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to create gRPC channel, source: {}", source))] CreateChannel { source: tonic::transport::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to create RecordBatch, source: {}", source))] @@ -61,7 +61,7 @@ pub enum Error { }, #[snafu(display("Failed to convert Arrow type: {}", from))] - Conversion { from: String, backtrace: Backtrace }, + Conversion { from: String, location: Location }, #[snafu(display("Column datatype error, source: {}", source))] ColumnDataType { @@ -72,14 +72,11 @@ pub enum Error { #[snafu(display("Failed to decode FlightData, source: {}", source))] DecodeFlightData { source: api::DecodeError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Invalid FlightData, reason: {}", reason))] - InvalidFlightData { - reason: String, - backtrace: Backtrace, - }, + InvalidFlightData { reason: String, location: Location }, #[snafu(display("Failed to convert Arrow Schema, source: {}", source))] ConvertArrowSchema { @@ -107,65 +104,7 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } } - -#[cfg(test)] -mod tests { - use snafu::{OptionExt, ResultExt}; - - use super::*; - - type StdResult = std::result::Result<(), E>; - - fn throw_none_option() -> Option { - None - } - - #[test] - fn test_missing_field_error() { - let e = throw_none_option() - .context(MissingFieldSnafu { field: "test" }) - .err() - .unwrap(); - - assert!(e.backtrace_opt().is_some()); - assert_eq!(e.status_code(), StatusCode::InvalidArguments); - } - - #[test] - fn test_type_mismatch_error() { - let e = throw_none_option() - .context(TypeMismatchSnafu { - column_name: "", - expected: "", - actual: "", - }) - .err() - .unwrap(); - - assert!(e.backtrace_opt().is_some()); - assert_eq!(e.status_code(), StatusCode::InvalidArguments); - } - - #[test] - fn test_create_channel_error() { - fn throw_tonic_error() -> StdResult { - tonic::transport::Endpoint::new("http//http").map(|_| ()) - } - - let e = throw_tonic_error() - .context(CreateChannelSnafu) - .err() - .unwrap(); - - assert!(e.backtrace_opt().is_some()); - assert_eq!(e.status_code(), StatusCode::Internal); - } -} diff --git a/src/common/mem-prof/src/error.rs b/src/common/mem-prof/src/error.rs index c325488d7f..432c528968 100644 --- a/src/common/mem-prof/src/error.rs +++ b/src/common/mem-prof/src/error.rs @@ -16,7 +16,7 @@ use std::any::Any; use std::path::PathBuf; use common_error::prelude::{ErrorExt, StatusCode}; -use snafu::{Backtrace, Snafu}; +use snafu::{Location, Snafu}; pub type Result = std::result::Result; @@ -30,7 +30,7 @@ pub enum Error { ProfilingNotEnabled, #[snafu(display("Failed to build temp file from given path: {:?}", path))] - BuildTempPath { path: PathBuf, backtrace: Backtrace }, + BuildTempPath { path: PathBuf, location: Location }, #[snafu(display("Failed to open temp file: {}", path))] OpenTempFile { @@ -56,10 +56,6 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - snafu::ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } diff --git a/src/common/procedure/src/error.rs b/src/common/procedure/src/error.rs index 8f9515dd9d..d67190d380 100644 --- a/src/common/procedure/src/error.rs +++ b/src/common/procedure/src/error.rs @@ -17,6 +17,7 @@ use std::string::FromUtf8Error; use std::sync::Arc; use common_error::prelude::*; +use snafu::Location; use crate::procedure::ProcedureId; @@ -34,18 +35,18 @@ pub enum Error { }, #[snafu(display("Loader {} is already registered", name))] - LoaderConflict { name: String, backtrace: Backtrace }, + LoaderConflict { name: String, location: Location }, #[snafu(display("Failed to serialize to json, source: {}", source))] ToJson { source: serde_json::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Procedure {} already exists", procedure_id))] DuplicateProcedure { procedure_id: ProcedureId, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to put state, key: '{key}', source: {source}"))] @@ -84,7 +85,7 @@ pub enum Error { #[snafu(display("Failed to deserialize from json, source: {}", source))] FromJson { source: serde_json::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Procedure exec failed, source: {}", source))] @@ -99,13 +100,13 @@ pub enum Error { #[snafu(display("Failed to wait watcher, source: {}", source))] WaitWatcher { source: tokio::sync::watch::error::RecvError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to execute procedure, source: {}", source))] ProcedureExec { source: Arc, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -147,10 +148,6 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } diff --git a/src/common/query/src/error.rs b/src/common/query/src/error.rs index 8788da9965..9325b0ca15 100644 --- a/src/common/query/src/error.rs +++ b/src/common/query/src/error.rs @@ -22,6 +22,7 @@ use datatypes::arrow; use datatypes::arrow::datatypes::DataType as ArrowDatatype; use datatypes::error::Error as DataTypeError; use datatypes::prelude::ConcreteDataType; +use snafu::Location; use statrs::StatsError; #[derive(Debug, Snafu)] @@ -31,7 +32,7 @@ pub enum Error { PyUdf { // TODO(discord9): find a way that prevent circle depend(query<-script<-query) and can use script's error type msg: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -46,20 +47,20 @@ pub enum Error { #[snafu(display("Fail to execute function, source: {}", source))] ExecuteFunction { source: DataFusionError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Unsupported input datatypes {:?} in function {}", datatypes, function))] UnsupportedInputDataType { function: String, datatypes: Vec, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Fail to generate function, source: {}", source))] GenerateFunction { source: StatsError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Fail to cast scalar value into vector: {}", source))] @@ -88,10 +89,7 @@ pub enum Error { DowncastVector { err_msg: String }, #[snafu(display("Bad accumulator implementation: {}", err_msg))] - BadAccumulatorImpl { - err_msg: String, - backtrace: Backtrace, - }, + BadAccumulatorImpl { err_msg: String, location: Location }, #[snafu(display("Invalid input type: {}", err_msg))] InvalidInputType { @@ -103,24 +101,24 @@ pub enum Error { #[snafu(display( "Illegal input_types status, check if DataFusion has changed its UDAF execution logic" ))] - InvalidInputState { backtrace: Backtrace }, + InvalidInputState { location: Location }, #[snafu(display("unexpected: not constant column"))] - InvalidInputCol { backtrace: Backtrace }, + InvalidInputCol { location: Location }, #[snafu(display("Not expected to run ExecutionPlan more than once"))] - ExecuteRepeatedly { backtrace: Backtrace }, + ExecuteRepeatedly { location: Location }, #[snafu(display("General DataFusion error, source: {}", source))] GeneralDataFusion { source: DataFusionError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to execute DataFusion ExecutionPlan, source: {}", source))] DataFusionExecutionPlan { source: DataFusionError, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -148,7 +146,7 @@ pub enum Error { TypeCast { source: ArrowError, typ: arrow::datatypes::DataType, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -157,7 +155,7 @@ pub enum Error { ))] ArrowCompute { source: ArrowError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Query engine fail to cast value: {}", source))] @@ -173,10 +171,7 @@ pub enum Error { }, #[snafu(display("Invalid function args: {}", err_msg))] - InvalidFuncArgs { - err_msg: String, - backtrace: Backtrace, - }, + InvalidFuncArgs { err_msg: String, location: Location }, } pub type Result = std::result::Result; @@ -216,10 +211,6 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } @@ -236,83 +227,3 @@ impl From for Error { Error::ExecutePhysicalPlan { source } } } - -#[cfg(test)] -mod tests { - use snafu::GenerateImplicitData; - - use super::*; - - fn throw_df_error() -> std::result::Result<(), DataFusionError> { - Err(DataFusionError::NotImplemented("test".to_string())) - } - - fn assert_error(err: &Error, code: StatusCode) { - let inner_err = err.as_any().downcast_ref::().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) - .err() - .unwrap(); - assert_error(&err, StatusCode::EngineExecuteQuery); - - let err: Error = throw_df_error() - .context(GeneralDataFusionSnafu) - .err() - .unwrap(); - assert_error(&err, StatusCode::Unexpected); - - let err = throw_df_error() - .context(DataFusionExecutionPlanSnafu) - .err() - .unwrap(); - assert_error(&err, StatusCode::Unexpected); - } - - #[test] - fn test_execute_repeatedly_error() { - let error = None::.context(ExecuteRepeatedlySnafu).err().unwrap(); - assert_eq!(error.status_code(), StatusCode::Unexpected); - assert!(error.backtrace_opt().is_some()); - } - - #[test] - fn test_convert_df_recordbatch_stream_error() { - let result: std::result::Result = - Err(common_recordbatch::error::Error::PollStream { - source: DataFusionError::Internal("blabla".to_string()), - backtrace: Backtrace::generate(), - }); - let error = result - .context(ConvertDfRecordBatchStreamSnafu) - .err() - .unwrap(); - assert_eq!(error.status_code(), StatusCode::Internal); - assert!(error.backtrace_opt().is_some()); - } - - fn raise_datatype_error() -> std::result::Result<(), DataTypeError> { - Err(DataTypeError::Conversion { - from: "test".to_string(), - backtrace: Backtrace::generate(), - }) - } - - #[test] - fn test_into_vector_error() { - let err = raise_datatype_error() - .context(IntoVectorSnafu { - data_type: ArrowDatatype::Int32, - }) - .err() - .unwrap(); - assert!(err.backtrace_opt().is_some()); - let datatype_err = raise_datatype_error().err().unwrap(); - assert_eq!(datatype_err.status_code(), err.status_code()); - } -} diff --git a/src/common/recordbatch/src/error.rs b/src/common/recordbatch/src/error.rs index 9f71da6fdd..53a63ded23 100644 --- a/src/common/recordbatch/src/error.rs +++ b/src/common/recordbatch/src/error.rs @@ -18,6 +18,7 @@ use std::any::Any; use common_error::ext::BoxedError; use common_error::prelude::*; use datatypes::prelude::ConcreteDataType; +use snafu::Location; pub type Result = std::result::Result; @@ -27,7 +28,7 @@ pub enum Error { #[snafu(display("Fail to create datafusion record batch, source: {}", source))] NewDfRecordBatch { source: datatypes::arrow::error::ArrowError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Data types error, source: {}", source))] @@ -43,40 +44,37 @@ pub enum Error { }, #[snafu(display("Failed to create RecordBatches, reason: {}", reason))] - CreateRecordBatches { - reason: String, - backtrace: Backtrace, - }, + CreateRecordBatches { reason: String, location: Location }, #[snafu(display("Failed to convert Arrow schema, source: {}", source))] SchemaConversion { source: datatypes::error::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to poll stream, source: {}", source))] PollStream { source: datafusion::error::DataFusionError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Fail to format record batch, source: {}", source))] Format { source: datatypes::arrow::error::ArrowError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to init Recordbatch stream, source: {}", source))] InitRecordbatchStream { source: datafusion_common::DataFusionError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Column {} not exists in table {}", column_name, table_name))] ColumnNotExists { column_name: String, table_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -113,10 +111,6 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } diff --git a/src/common/runtime/src/error.rs b/src/common/runtime/src/error.rs index 49088825a9..e7ba69a4ff 100644 --- a/src/common/runtime/src/error.rs +++ b/src/common/runtime/src/error.rs @@ -15,6 +15,7 @@ use std::any::Any; use common_error::prelude::*; +use snafu::Location; use tokio::task::JoinError; pub type Result = std::result::Result; @@ -25,10 +26,10 @@ pub enum Error { #[snafu(display("Failed to build runtime, source: {}", source))] BuildRuntime { source: std::io::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Repeated task {} not started yet", name))] - IllegalState { name: String, backtrace: Backtrace }, + IllegalState { name: String, location: Location }, #[snafu(display( "Failed to wait for repeated task {} to stop, source: {}", @@ -38,16 +39,20 @@ pub enum Error { WaitGcTaskStop { name: String, source: JoinError, - backtrace: Backtrace, + location: Location, }, } impl ErrorExt for Error { - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } + + fn location_opt(&self) -> Option { + match self { + Error::BuildRuntime { location, .. } + | Error::IllegalState { location, .. } + | Error::WaitGcTaskStop { location, .. } => Some(*location), + } + } } diff --git a/src/common/substrait/src/error.rs b/src/common/substrait/src/error.rs index b2d4282620..b8a740878e 100644 --- a/src/common/substrait/src/error.rs +++ b/src/common/substrait/src/error.rs @@ -18,61 +18,58 @@ use common_error::prelude::{BoxedError, ErrorExt, StatusCode}; use datafusion::error::DataFusionError; use datatypes::prelude::ConcreteDataType; use prost::{DecodeError, EncodeError}; -use snafu::{Backtrace, ErrorCompat, Snafu}; +use snafu::{Location, Snafu}; #[derive(Debug, Snafu)] #[snafu(visibility(pub))] pub enum Error { #[snafu(display("Unsupported physical plan: {}", name))] - UnsupportedPlan { name: String, backtrace: Backtrace }, + UnsupportedPlan { name: String, location: Location }, #[snafu(display("Unsupported expr: {}", name))] - UnsupportedExpr { name: String, backtrace: Backtrace }, + UnsupportedExpr { name: String, location: Location }, #[snafu(display("Unsupported concrete type: {:?}", ty))] UnsupportedConcreteType { ty: ConcreteDataType, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Unsupported substrait type: {}", ty))] - UnsupportedSubstraitType { ty: String, backtrace: Backtrace }, + UnsupportedSubstraitType { ty: String, location: Location }, #[snafu(display("Failed to decode substrait relation, source: {}", source))] DecodeRel { source: DecodeError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to encode substrait relation, source: {}", source))] EncodeRel { source: EncodeError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Input plan is empty"))] - EmptyPlan { backtrace: Backtrace }, + EmptyPlan { location: Location }, #[snafu(display("Input expression is empty"))] - EmptyExpr { backtrace: Backtrace }, + EmptyExpr { location: Location }, #[snafu(display("Missing required field in protobuf, field: {}, plan: {}", field, plan))] MissingField { field: String, plan: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Invalid parameters: {}", reason))] - InvalidParameters { - reason: String, - backtrace: Backtrace, - }, + InvalidParameters { reason: String, location: Location }, #[snafu(display("Internal error from DataFusion: {}", source))] DFInternal { source: DataFusionError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Internal error: {}", source))] @@ -82,10 +79,10 @@ pub enum Error { }, #[snafu(display("Table querying not found: {}", name))] - TableNotFound { name: String, backtrace: Backtrace }, + TableNotFound { name: String, location: Location }, #[snafu(display("Cannot convert plan doesn't belong to GreptimeDB"))] - UnknownPlan { backtrace: Backtrace }, + UnknownPlan { location: Location }, #[snafu(display( "Schema from Substrait proto doesn't match with the schema in storage. @@ -97,7 +94,7 @@ pub enum Error { SchemaNotMatch { substrait_schema: datafusion::arrow::datatypes::SchemaRef, storage_schema: datafusion::arrow::datatypes::SchemaRef, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to convert DataFusion schema, source: {}", source))] @@ -138,10 +135,6 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } diff --git a/src/common/telemetry/src/macros.rs b/src/common/telemetry/src/macros.rs index dcae8bd14d..3ad473b344 100644 --- a/src/common/telemetry/src/macros.rs +++ b/src/common/telemetry/src/macros.rs @@ -38,15 +38,15 @@ macro_rules! error { ($e:expr; target: $target:expr, $($arg:tt)+) => ({ use $crate::common_error::ext::ErrorExt; use std::error::Error; - match ($e.source(), $e.backtrace_opt()) { - (Some(source), Some(backtrace)) => { + match ($e.source(), $e.location_opt()) { + (Some(source), Some(location)) => { $crate::log!( target: $target, $crate::logging::Level::ERROR, err.msg = %$e, err.code = %$e.status_code(), err.source = source, - err.backtrace = %backtrace, + err.location = %location, $($arg)+ ) }, @@ -60,13 +60,13 @@ macro_rules! error { $($arg)+ ) }, - (None, Some(backtrace)) => { + (None, Some(location)) => { $crate::log!( target: $target, $crate::logging::Level::ERROR, err.msg = %$e, err.code = %$e.status_code(), - err.backtrace = %backtrace, + err.location = %location, $($arg)+ ) }, @@ -86,14 +86,14 @@ macro_rules! error { ($e:expr; $($arg:tt)+) => ({ use std::error::Error; use $crate::common_error::ext::ErrorExt; - match ($e.source(), $e.backtrace_opt()) { - (Some(source), Some(backtrace)) => { + match ($e.source(), $e.location_opt()) { + (Some(source), Some(location)) => { $crate::log!( $crate::logging::Level::ERROR, err.msg = %$e, err.code = %$e.status_code(), err.source = source, - err.backtrace = %backtrace, + err.location = %location, $($arg)+ ) }, @@ -106,12 +106,12 @@ macro_rules! error { $($arg)+ ) }, - (None, Some(backtrace)) => { + (None, Some(location)) => { $crate::log!( $crate::logging::Level::ERROR, err.msg = %$e, err.code = %$e.status_code(), - err.backtrace = %backtrace, + err.location = %location, $($arg)+ ) }, @@ -263,9 +263,6 @@ mod tests { error!(err_ref2; "hello {}", "world"); error!("hello {}", "world"); - let err = MockError::with_backtrace(StatusCode::Internal); - error!(err; "Error with backtrace hello {}", "world"); - let root_err = MockError::with_source(err); error!(root_err; "Error with source hello {}", "world"); } diff --git a/src/common/time/src/error.rs b/src/common/time/src/error.rs index c6603ef80f..f62ead4d88 100644 --- a/src/common/time/src/error.rs +++ b/src/common/time/src/error.rs @@ -18,7 +18,7 @@ use std::num::TryFromIntError; use chrono::ParseError; use common_error::ext::ErrorExt; use common_error::prelude::StatusCode; -use snafu::{Backtrace, ErrorCompat, Snafu}; +use snafu::{Location, Snafu}; #[derive(Debug, Snafu)] #[snafu(visibility(pub))] @@ -27,16 +27,16 @@ pub enum Error { ParseDateStr { raw: String, source: ParseError }, #[snafu(display("Failed to parse a string into Timestamp, raw string: {}", raw))] - ParseTimestamp { raw: String, backtrace: Backtrace }, + ParseTimestamp { raw: String, location: Location }, #[snafu(display("Current timestamp overflow, source: {}", source))] TimestampOverflow { source: TryFromIntError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Timestamp arithmetic overflow, msg: {}", msg))] - ArithmeticOverflow { msg: String, backtrace: Backtrace }, + ArithmeticOverflow { msg: String, location: Location }, } impl ErrorExt for Error { @@ -50,33 +50,18 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } + + fn location_opt(&self) -> Option { + match self { + Error::ParseTimestamp { location, .. } + | Error::TimestampOverflow { location, .. } + | Error::ArithmeticOverflow { location, .. } => Some(*location), + Error::ParseDateStr { .. } => None, + } + } } pub type Result = std::result::Result; - -#[cfg(test)] -mod tests { - use chrono::NaiveDateTime; - use snafu::ResultExt; - - use super::*; - - #[test] - fn test_errors() { - let raw = "2020-09-08T13:42:29.190855Z"; - let result = NaiveDateTime::parse_from_str(raw, "%F").context(ParseDateStrSnafu { raw }); - assert!(matches!(result.err().unwrap(), Error::ParseDateStr { .. })); - - assert_eq!( - "Failed to parse a string into Timestamp, raw string: 2020-09-08T13:42:29.190855Z", - ParseTimestampSnafu { raw }.build().to_string() - ); - } -} diff --git a/src/datanode/src/error.rs b/src/datanode/src/error.rs index 730da2422a..6e627793de 100644 --- a/src/datanode/src/error.rs +++ b/src/datanode/src/error.rs @@ -18,6 +18,7 @@ use common_datasource::error::Error as DataSourceError; use common_error::prelude::*; use common_procedure::ProcedureId; use datafusion::parquet; +use snafu::Location; use storage::error::Error as StorageError; use table::error::Error as TableError; use url::ParseError; @@ -59,7 +60,7 @@ pub enum Error { }, #[snafu(display("Incorrect internal state: {}", state))] - IncorrectInternalState { state: String, backtrace: Backtrace }, + IncorrectInternalState { state: String, location: Location }, #[snafu(display("Failed to create catalog list, source: {}", source))] NewCatalog { @@ -68,10 +69,10 @@ pub enum Error { }, #[snafu(display("Catalog not found: {}", name))] - CatalogNotFound { name: String, backtrace: Backtrace }, + CatalogNotFound { name: String, location: Location }, #[snafu(display("Schema not found: {}", name))] - SchemaNotFound { name: String, backtrace: Backtrace }, + SchemaNotFound { name: String, location: Location }, #[snafu(display("Failed to create table: {}, source: {}", table_name, source))] CreateTable { @@ -111,7 +112,7 @@ pub enum Error { #[snafu(display("Table not found: {}", table_name))] TableNotFound { table_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Column {} not found in table {}", column_name, table_name))] @@ -121,7 +122,7 @@ pub enum Error { }, #[snafu(display("Missing timestamp column in request"))] - MissingTimestampColumn { backtrace: Backtrace }, + MissingTimestampColumn { location: Location }, #[snafu(display( "Columns and values number mismatch, columns: {}, values: {}", @@ -137,7 +138,7 @@ pub enum Error { }, #[snafu(display("Missing insert body"))] - MissingInsertBody { backtrace: Backtrace }, + MissingInsertBody { location: Location }, #[snafu(display("Failed to insert value to table: {}, source: {}", table_name, source))] Insert { @@ -204,7 +205,7 @@ pub enum Error { InitBackend { config: Box, source: object_store::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to build backend, source: {}", source))] @@ -216,7 +217,7 @@ pub enum Error { #[snafu(display("Failed to parse url, source: {}", source))] ParseUrl { source: DataSourceError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Runtime resource error, source: {}", source))] @@ -242,7 +243,7 @@ pub enum Error { #[snafu(display("Failed to regex, source: {}", source))] BuildRegex { - backtrace: Backtrace, + location: Location, source: regex::Error, }, @@ -268,10 +269,10 @@ pub enum Error { }, #[snafu(display("Specified timestamp key or primary key column not found: {}", name))] - KeyColumnNotFound { name: String, backtrace: Backtrace }, + KeyColumnNotFound { name: String, location: Location }, #[snafu(display("Illegal primary keys definition: {}", msg))] - IllegalPrimaryKeysDef { msg: String, backtrace: Backtrace }, + IllegalPrimaryKeysDef { msg: String, location: Location }, #[snafu(display( "Constraint in CREATE TABLE statement is not supported yet: {}", @@ -279,7 +280,7 @@ pub enum Error { ))] ConstraintNotSupported { constraint: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to insert into system catalog table, source: {}", source))] @@ -301,7 +302,7 @@ pub enum Error { }, #[snafu(display("Schema {} already exists", name))] - SchemaExists { name: String, backtrace: Backtrace }, + SchemaExists { name: String, location: Location }, #[snafu(display("Failed to convert alter expr to request: {}", source))] AlterExprToRequest { @@ -359,7 +360,7 @@ pub enum Error { #[snafu(display( "Table id provider not found, cannot execute SQL directly on datanode in distributed mode" ))] - TableIdProviderNotFound { backtrace: Backtrace }, + TableIdProviderNotFound { location: Location }, #[snafu(display("Failed to bump table id, source: {}", source))] BumpTableId { @@ -374,13 +375,13 @@ pub enum Error { }, #[snafu(display("Missing node id option in distributed mode"))] - MissingNodeId { backtrace: Backtrace }, + MissingNodeId { location: Location }, #[snafu(display("Missing node id option in distributed mode"))] - MissingMetasrvOpts { backtrace: Backtrace }, + MissingMetasrvOpts { location: Location }, #[snafu(display("Missing required field: {}", name))] - MissingRequiredField { name: String, backtrace: Backtrace }, + MissingRequiredField { name: String, location: Location }, #[snafu(display("Cannot find requested database: {}-{}", catalog, schema))] DatabaseNotFound { catalog: String, schema: String }, @@ -400,10 +401,7 @@ pub enum Error { "No valid default value can be built automatically, column: {}", column, ))] - ColumnNoneDefaultValue { - column: String, - backtrace: Backtrace, - }, + ColumnNoneDefaultValue { column: String, location: Location }, #[snafu(display("Failed to describe schema for given statement, source: {}", source))] DescribeStatement { @@ -437,32 +435,32 @@ pub enum Error { #[snafu(display("Failed to read parquet file, source: {}", source))] ReadParquet { source: parquet::errors::ParquetError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to poll stream, source: {}", source))] PollStream { source: datafusion_common::DataFusionError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to build parquet record batch stream, source: {}", source))] BuildParquetRecordBatchStream { - backtrace: Backtrace, + location: Location, source: parquet::errors::ParquetError, }, #[snafu(display("Failed to read object in path: {}, source: {}", path, source))] ReadObject { path: String, - backtrace: Backtrace, + location: Location, source: object_store::Error, }, #[snafu(display("Failed to write object into path: {}, source: {}", path, source))] WriteObject { path: String, - backtrace: Backtrace, + location: Location, source: object_store::Error, }, @@ -619,10 +617,6 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } @@ -636,62 +630,10 @@ impl From for tonic::Status { #[cfg(test)] mod tests { - use std::error::Error as StdError; use std::str::FromStr; - use common_error::ext::BoxedError; - use common_error::mock::MockError; - use super::*; - fn throw_query_error() -> std::result::Result<(), query::error::Error> { - query::error::CatalogNotFoundSnafu { - catalog: String::new(), - } - .fail() - } - - fn throw_catalog_error() -> catalog::error::Result<()> { - Err(catalog::error::Error::SchemaProviderOperation { - source: BoxedError::new(MockError::with_backtrace(StatusCode::Internal)), - }) - } - - fn assert_internal_error(err: &Error) { - assert!(err.backtrace_opt().is_some()); - assert_eq!(StatusCode::Internal, err.status_code()); - } - - fn assert_invalid_argument_error(err: &Error) { - assert!(err.backtrace_opt().is_some()); - assert_eq!(StatusCode::InvalidArguments, err.status_code()); - } - - fn assert_tonic_internal_error(err: Error) { - let status_code = err.status_code(); - let err_string = err.to_string(); - - let s: tonic::Status = err.into(); - assert_eq!(s.code(), tonic::Code::Unknown); - - let source = s.source().unwrap().downcast_ref::().unwrap(); - assert_eq!(source.status_code(), status_code); - assert_eq!(source.to_string(), err_string); - } - - #[test] - fn test_error() { - let err = throw_query_error().context(ExecuteSqlSnafu).err().unwrap(); - assert_invalid_argument_error(&err); - assert_tonic_internal_error(err); - let err = throw_catalog_error() - .context(NewCatalogSnafu) - .err() - .unwrap(); - assert_internal_error(&err); - assert_tonic_internal_error(err); - } - #[test] fn test_parse_timestamp() { let err = common_time::timestamp::Timestamp::from_str("test") diff --git a/src/datatypes/src/error.rs b/src/datatypes/src/error.rs index cab8fc5d71..dc9925009f 100644 --- a/src/datatypes/src/error.rs +++ b/src/datatypes/src/error.rs @@ -14,8 +14,8 @@ use std::any::Any; -use common_error::prelude::{ErrorCompat, ErrorExt, Snafu, StatusCode}; -use snafu::Backtrace; +use common_error::prelude::{ErrorExt, Snafu, StatusCode}; +use snafu::Location; #[derive(Debug, Snafu)] #[snafu(visibility(pub))] @@ -23,44 +23,44 @@ pub enum Error { #[snafu(display("Failed to serialize data, source: {}", source))] Serialize { source: serde_json::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to deserialize data, source: {}, json: {}", source, json))] Deserialize { source: serde_json::Error, - backtrace: Backtrace, + location: Location, json: String, }, #[snafu(display("Failed to convert datafusion type: {}", from))] - Conversion { from: String, backtrace: Backtrace }, + Conversion { from: String, location: Location }, #[snafu(display("Bad array access, Index out of bounds: {}, size: {}", index, size))] BadArrayAccess { index: usize, size: usize, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Unknown vector, {}", msg))] - UnknownVector { msg: String, backtrace: Backtrace }, + UnknownVector { msg: String, location: Location }, #[snafu(display("Unsupported arrow data type, type: {:?}", arrow_type))] UnsupportedArrowType { arrow_type: arrow::datatypes::DataType, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Unsupported operation: {} for vector: {}", op, vector_type))] UnsupportedOperation { op: String, vector_type: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Timestamp column {} not found", name,))] - TimestampNotFound { name: String, backtrace: Backtrace }, + TimestampNotFound { name: String, location: Location }, #[snafu(display( "Failed to parse version in schema meta, value: {}, source: {}", @@ -70,54 +70,45 @@ pub enum Error { ParseSchemaVersion { value: String, source: std::num::ParseIntError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Invalid timestamp index: {}", index))] - InvalidTimestampIndex { index: usize, backtrace: Backtrace }, + InvalidTimestampIndex { index: usize, location: Location }, #[snafu(display("Duplicate timestamp index, exists: {}, new: {}", exists, new))] DuplicateTimestampIndex { exists: usize, new: usize, - backtrace: Backtrace, + location: Location, }, #[snafu(display("{}", msg))] - CastType { msg: String, backtrace: Backtrace }, + CastType { msg: String, location: Location }, #[snafu(display("Arrow failed to compute, source: {}", source))] ArrowCompute { source: arrow::error::ArrowError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Unsupported column default constraint expression: {}", expr))] - UnsupportedDefaultExpr { expr: String, backtrace: Backtrace }, + UnsupportedDefaultExpr { expr: String, location: Location }, #[snafu(display("Default value should not be null for non null column"))] - NullDefault { backtrace: Backtrace }, + NullDefault { location: Location }, #[snafu(display("Incompatible default value type, reason: {}", reason))] - DefaultValueType { - reason: String, - backtrace: Backtrace, - }, + DefaultValueType { reason: String, location: Location }, #[snafu(display("Duplicated metadata for {}", key))] - DuplicateMeta { key: String, backtrace: Backtrace }, + DuplicateMeta { key: String, location: Location }, #[snafu(display("Failed to convert value into scalar value, reason: {}", reason))] - ToScalarValue { - reason: String, - backtrace: Backtrace, - }, + ToScalarValue { reason: String, location: Location }, #[snafu(display("Invalid timestamp precision: {}", precision))] - InvalidTimestampPrecision { - precision: u64, - backtrace: Backtrace, - }, + InvalidTimestampPrecision { precision: u64, location: Location }, } impl ErrorExt for Error { @@ -126,38 +117,9 @@ impl ErrorExt for Error { StatusCode::Internal } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } } pub type Result = std::result::Result; - -#[cfg(test)] -mod tests { - use std::collections::HashMap; - - use snafu::ResultExt; - - use super::*; - - #[test] - pub fn test_error() { - let mut map = HashMap::new(); - map.insert(true, 1); - map.insert(false, 2); - - let result = serde_json::to_string(&map).context(SerializeSnafu); - assert!(result.is_err(), "serialize result is: {result:?}"); - let err = serde_json::to_string(&map) - .context(SerializeSnafu) - .err() - .unwrap(); - assert!(err.backtrace_opt().is_some()); - assert_eq!(StatusCode::Internal, err.status_code()); - } -} diff --git a/src/frontend/src/error.rs b/src/frontend/src/error.rs index 2eec308447..91eec274ed 100644 --- a/src/frontend/src/error.rs +++ b/src/frontend/src/error.rs @@ -15,6 +15,7 @@ use std::any::Any; use common_error::prelude::*; +use snafu::Location; use store_api::storage::RegionId; #[derive(Debug, Snafu)] @@ -63,7 +64,7 @@ pub enum Error { }, #[snafu(display("Missing insert values"))] - MissingInsertValues { backtrace: Backtrace }, + MissingInsertValues { location: Location }, #[snafu(display("Column datatype error, source: {}", source))] ColumnDataType { @@ -94,46 +95,34 @@ pub enum Error { }, #[snafu(display("Invalid SQL, error: {}", err_msg))] - InvalidSql { - err_msg: String, - backtrace: Backtrace, - }, + InvalidSql { err_msg: String, location: Location }, #[snafu(display("Illegal Frontend state: {}", err_msg))] - IllegalFrontendState { - err_msg: String, - backtrace: Backtrace, - }, + IllegalFrontendState { err_msg: String, location: Location }, #[snafu(display("Incomplete GRPC result: {}", err_msg))] - IncompleteGrpcResult { - err_msg: String, - backtrace: Backtrace, - }, + IncompleteGrpcResult { err_msg: String, location: Location }, #[snafu(display("Failed to find Datanode by region: {:?}", region))] FindDatanode { region: RegionId, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Invalid InsertRequest, reason: {}", reason))] - InvalidInsertRequest { - reason: String, - backtrace: Backtrace, - }, + InvalidInsertRequest { reason: String, location: Location }, #[snafu(display("Table `{}` not exist", table_name))] TableNotFound { table_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Column {} not found in table {}", column_name, table_name))] ColumnNotFound { column_name: String, table_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -144,13 +133,13 @@ pub enum Error { ColumnValuesNumberMismatch { columns: usize, values: usize, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to join task, source: {}", source))] JoinTask { source: common_runtime::JoinError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("General catalog error: {}", source))] @@ -180,7 +169,7 @@ pub enum Error { #[snafu(display("Failed to create table route for table {}", table_name))] CreateTableRoute { table_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to find table route for table {}", table_name))] @@ -214,17 +203,17 @@ pub enum Error { #[snafu(display("Failed to find catalog by name: {}", catalog_name))] CatalogNotFound { catalog_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to find schema, schema info: {}", schema_info))] SchemaNotFound { schema_info: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Schema {} already exists", name))] - SchemaExists { name: String, backtrace: Backtrace }, + SchemaExists { name: String, location: Location }, #[snafu(display("Table occurs error, source: {}", source))] Table { @@ -235,11 +224,11 @@ pub enum Error { #[snafu(display("Failed to find region route for table {}", table_name))] FindRegionRoute { table_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Cannot find primary key column by name: {}", msg))] - PrimaryKeyNotFound { msg: String, backtrace: Backtrace }, + PrimaryKeyNotFound { msg: String, location: Location }, #[snafu(display("Failed to execute statement, source: {}", source))] ExecuteStatement { @@ -268,7 +257,7 @@ pub enum Error { #[snafu(display("Failed to build DataFusion logical plan, source: {}", source))] BuildDfLogicalPlan { source: datafusion_common::DataFusionError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("{source}"))] @@ -278,7 +267,7 @@ pub enum Error { }, #[snafu(display("Missing meta_client_options section in config"))] - MissingMetasrvOpts { backtrace: Backtrace }, + MissingMetasrvOpts { location: Location }, #[snafu(display("Failed to convert AlterExpr to AlterRequest, source: {}", source))] AlterExprToRequest { @@ -287,10 +276,10 @@ pub enum Error { }, #[snafu(display("Failed to find leaders when altering table, table: {}", table))] - LeaderNotFound { table: String, backtrace: Backtrace }, + LeaderNotFound { table: String, location: Location }, #[snafu(display("Table already exists: `{}`", table))] - TableAlreadyExist { table: String, backtrace: Backtrace }, + TableAlreadyExist { table: String, location: Location }, #[snafu(display("Failed to encode Substrait logical plan, source: {}", source))] EncodeSubstraitLogicalPlan { @@ -299,7 +288,7 @@ pub enum Error { }, #[snafu(display("Failed to found context value: {}", key))] - ContextValueNotFound { key: String, backtrace: Backtrace }, + ContextValueNotFound { key: String, location: Location }, #[snafu(display( "Failed to build table meta for table: {}, source: {}", @@ -309,7 +298,7 @@ pub enum Error { BuildTableMeta { table_name: String, source: table::metadata::TableMetaBuilderError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Not supported: {}", feat))] @@ -336,10 +325,7 @@ pub enum Error { "No valid default value can be built automatically, column: {}", column, ))] - ColumnNoneDefaultValue { - column: String, - backtrace: Backtrace, - }, + ColumnNoneDefaultValue { column: String, location: Location }, #[snafu(display("SQL execution intercepted, source: {}", source))] SqlExecIntercepted { @@ -371,7 +357,7 @@ pub enum Error { }, #[snafu(display("Illegal primary keys definition: {}", msg))] - IllegalPrimaryKeysDef { msg: String, backtrace: Backtrace }, + IllegalPrimaryKeysDef { msg: String, location: Location }, #[snafu(display("Unrecognized table option: {}", source))] UnrecognizedTableOption { @@ -473,10 +459,6 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } diff --git a/src/log-store/src/error.rs b/src/log-store/src/error.rs index 2136e79f3a..646798c4b0 100644 --- a/src/log-store/src/error.rs +++ b/src/log-store/src/error.rs @@ -16,7 +16,7 @@ use std::any::Any; use common_error::prelude::{ErrorExt, Snafu}; use common_runtime::error::Error as RuntimeError; -use snafu::{Backtrace, ErrorCompat}; +use snafu::Location; #[derive(Debug, Snafu)] #[snafu(visibility(pub))] @@ -36,20 +36,20 @@ pub enum Error { #[snafu(display("Failed to add entry to LogBatch, source: {}", source))] AddEntryLogBatch { source: raft_engine::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to perform raft-engine operation, source: {}", source))] RaftEngine { source: raft_engine::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Log store not started yet"))] - IllegalState { backtrace: Backtrace }, + IllegalState { location: Location }, #[snafu(display("Namespace is illegal: {}", ns))] - IllegalNamespace { ns: u64, backtrace: Backtrace }, + IllegalNamespace { ns: u64, location: Location }, #[snafu(display( "Failed to fetch entries from namespace: {}, start: {}, end: {}, max size: {}, source: {}", @@ -65,15 +65,11 @@ pub enum Error { end: u64, max_size: usize, source: raft_engine::Error, - backtrace: Backtrace, + location: Location, }, } impl ErrorExt for Error { - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } diff --git a/src/meta-client/src/error.rs b/src/meta-client/src/error.rs index 1df4e05c5c..ebca90801f 100644 --- a/src/meta-client/src/error.rs +++ b/src/meta-client/src/error.rs @@ -13,6 +13,7 @@ // limitations under the License. use common_error::prelude::*; +use snafu::Location; #[derive(Debug, Snafu)] #[snafu(visibility(pub))] @@ -21,26 +22,23 @@ pub enum Error { ConnectFailed { url: String, source: tonic::transport::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Illegal GRPC client state: {}", err_msg))] - IllegalGrpcClientState { - err_msg: String, - backtrace: Backtrace, - }, + IllegalGrpcClientState { err_msg: String, location: Location }, #[snafu(display("Tonic internal error, source: {}", source))] TonicStatus { source: tonic::Status, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to ask leader from all endpoints"))] - AskLeader { backtrace: Backtrace }, + AskLeader { location: Location }, #[snafu(display("No leader, should ask leader first"))] - NoLeader { backtrace: Backtrace }, + NoLeader { location: Location }, #[snafu(display("Failed to create gRPC channel, source: {}", source))] CreateChannel { @@ -49,34 +47,28 @@ pub enum Error { }, #[snafu(display("{} not started", name))] - NotStarted { name: String, backtrace: Backtrace }, + NotStarted { name: String, location: Location }, #[snafu(display("Failed to send heartbeat: {}", err_msg))] - SendHeartbeat { - err_msg: String, - backtrace: Backtrace, - }, + SendHeartbeat { err_msg: String, location: Location }, #[snafu(display("Failed create heartbeat stream to server"))] - CreateHeartbeatStream { backtrace: Backtrace }, + CreateHeartbeatStream { location: Location }, #[snafu(display("Route info corrupted: {}", err_msg))] - RouteInfoCorrupted { - err_msg: String, - backtrace: Backtrace, - }, + RouteInfoCorrupted { err_msg: String, location: Location }, #[snafu(display("Illegal state from server, code: {}, error: {}", code, err_msg))] IllegalServerState { code: i32, err_msg: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to serde json, source: {}", source))] SerdeJson { source: serde_json::error::Error, - backtrace: Backtrace, + location: Location, }, } @@ -84,10 +76,6 @@ pub enum Error { pub type Result = std::result::Result; impl ErrorExt for Error { - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn std::any::Any { self } diff --git a/src/meta-srv/src/error.rs b/src/meta-srv/src/error.rs index e2c526b2e9..dbf6d9b6f9 100644 --- a/src/meta-srv/src/error.rs +++ b/src/meta-srv/src/error.rs @@ -15,6 +15,7 @@ use std::string::FromUtf8Error; use common_error::prelude::*; +use snafu::Location; use tokio::sync::mpsc::error::SendError; use tonic::codegen::http; use tonic::{Code, Status}; @@ -33,34 +34,34 @@ pub enum Error { }, #[snafu(display("Error stream request next is None"))] - StreamNone { backtrace: Backtrace }, + StreamNone { location: Location }, #[snafu(display("Empty key is not allowed"))] - EmptyKey { backtrace: Backtrace }, + EmptyKey { location: Location }, #[snafu(display("Failed to execute via Etcd, source: {}", source))] EtcdFailed { source: etcd_client::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to connect to Etcd, source: {}", source))] ConnectEtcd { source: etcd_client::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to bind address {}, source: {}", addr, source))] TcpBind { addr: String, source: std::io::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to start gRPC server, source: {}", source))] StartGrpc { source: tonic::transport::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to start http server, source: {}", source))] StartHttp { @@ -73,70 +74,64 @@ pub enum Error { source: std::net::AddrParseError, }, #[snafu(display("Empty table name"))] - EmptyTableName { backtrace: Backtrace }, + EmptyTableName { location: Location }, #[snafu(display("Invalid datanode lease key: {}", key))] - InvalidLeaseKey { key: String, backtrace: Backtrace }, + InvalidLeaseKey { key: String, location: Location }, #[snafu(display("Invalid datanode stat key: {}", key))] - InvalidStatKey { key: String, backtrace: Backtrace }, + InvalidStatKey { key: String, location: Location }, #[snafu(display("Failed to parse datanode lease key from utf8: {}", source))] LeaseKeyFromUtf8 { source: std::string::FromUtf8Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to parse datanode lease value from utf8: {}", source))] LeaseValueFromUtf8 { source: std::string::FromUtf8Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to parse datanode stat key from utf8: {}", source))] StatKeyFromUtf8 { source: std::string::FromUtf8Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to parse datanode stat value from utf8: {}", source))] StatValueFromUtf8 { source: std::string::FromUtf8Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to serialize to json: {}", input))] SerializeToJson { input: String, source: serde_json::error::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to deserialize from json: {}", input))] DeserializeFromJson { input: String, source: serde_json::error::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to parse number: {}, source: {}", err_msg, source))] ParseNum { err_msg: String, source: std::num::ParseIntError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Invalid arguments: {}", err_msg))] - InvalidArguments { - err_msg: String, - backtrace: Backtrace, - }, + InvalidArguments { err_msg: String, location: Location }, #[snafu(display("Invalid result with a txn response: {}", err_msg))] - InvalidTxnResult { - err_msg: String, - backtrace: Backtrace, - }, + InvalidTxnResult { err_msg: String, location: Location }, #[snafu(display("Cannot parse catalog value, source: {}", source))] InvalidCatalogValue { @@ -145,61 +140,55 @@ pub enum Error { }, #[snafu(display("Unexcepted sequence value: {}", err_msg))] - UnexceptedSequenceValue { - err_msg: String, - backtrace: Backtrace, - }, + UnexceptedSequenceValue { err_msg: String, location: Location }, #[snafu(display("Failed to decode table route, source: {}", source))] DecodeTableRoute { source: prost::DecodeError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Table route not found: {}", key))] - TableRouteNotFound { key: String, backtrace: Backtrace }, + TableRouteNotFound { key: String, location: Location }, #[snafu(display("Failed to get sequence: {}", err_msg))] - NextSequence { - err_msg: String, - backtrace: Backtrace, - }, + NextSequence { err_msg: String, location: Location }, #[snafu(display("MetaSrv has no leader at this moment"))] - NoLeader { backtrace: Backtrace }, + NoLeader { location: Location }, #[snafu(display("Table {} not found", name))] - TableNotFound { name: String, backtrace: Backtrace }, + TableNotFound { name: String, location: Location }, #[snafu(display( "Failed to move the value of {} because other clients caused a race condition", key ))] - MoveValue { key: String, backtrace: Backtrace }, + MoveValue { key: String, location: Location }, #[snafu(display("Unsupported selector type, {}", selector_type))] UnsupportedSelectorType { selector_type: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to decode table global value, source: {}", source))] DecodeTableGlobalValue { source: prost::DecodeError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Unexpected, violated: {}", violated))] Unexpected { violated: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Invalid KVs length, expected: {}, actual: {}", expected, actual))] InvalidKvsLength { expected: usize, actual: usize, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to create gRPC channel, source: {}", source))] @@ -214,7 +203,7 @@ pub enum Error { ))] BatchGet { source: tonic::Status, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -223,25 +212,25 @@ pub enum Error { ))] Range { source: tonic::Status, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Response header not found"))] - ResponseHeaderNotFound { backtrace: Backtrace }, + ResponseHeaderNotFound { location: Location }, #[snafu(display("The requested meta node is not leader, node addr: {}", node_addr))] IsNotLeader { node_addr: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("MetaSrv has no meta peer client"))] - NoMetaPeerClient { backtrace: Backtrace }, + NoMetaPeerClient { location: Location }, #[snafu(display("Invalid http body, source: {}", source))] InvalidHttpBody { source: http::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -252,7 +241,7 @@ pub enum Error { ExceededRetryLimit { func_name: String, retry_num: usize, - backtrace: Backtrace, + location: Location, }, #[snafu(display("An error occurred in Meta, source: {}", source))] @@ -264,28 +253,28 @@ pub enum Error { #[snafu(display("Failed to lock based on etcd, source: {}", source))] Lock { source: etcd_client::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to unlock based on etcd, source: {}", source))] Unlock { source: etcd_client::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to grant lease, source: {}", source))] LeaseGrant { source: etcd_client::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Distributed lock is not configured"))] - LockNotConfig { backtrace: Backtrace }, + LockNotConfig { location: Location }, #[snafu(display("Invalid utf-8 value, source: {:?}", source))] InvalidUtf8Value { source: FromUtf8Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Missing required parameter, param: {:?}", param))] @@ -307,10 +296,6 @@ impl From for Status { } impl ErrorExt for Error { - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn std::any::Any { self } @@ -395,166 +380,3 @@ pub(crate) fn match_for_io_error(err_status: &Status) -> Option<&std::io::Error> }; } } - -#[cfg(test)] -mod tests { - use super::*; - - type StdResult = std::result::Result<(), E>; - - fn throw_none_option() -> Option { - None - } - - fn throw_etcd_client_error() -> StdResult { - Err(etcd_client::Error::InvalidArgs("".to_string())) - } - - fn throw_serde_json_error() -> StdResult { - serde_json::from_str("invalid json") - } - - #[test] - fn test_stream_node_error() { - let e = throw_none_option().context(StreamNoneSnafu).err().unwrap(); - assert!(e.backtrace_opt().is_some()); - assert_eq!(e.status_code(), StatusCode::Internal); - } - - #[test] - fn test_empty_key_error() { - let e = throw_none_option().context(EmptyKeySnafu).err().unwrap(); - assert!(e.backtrace_opt().is_some()); - assert_eq!(e.status_code(), StatusCode::InvalidArguments); - } - - #[test] - fn test_etcd_failed_error() { - let e = throw_etcd_client_error() - .context(EtcdFailedSnafu) - .err() - .unwrap(); - assert!(e.backtrace_opt().is_some()); - assert_eq!(e.status_code(), StatusCode::Internal); - } - - #[test] - fn test_connect_etcd_error() { - let e = throw_etcd_client_error() - .context(ConnectEtcdSnafu) - .err() - .unwrap(); - assert!(e.backtrace_opt().is_some()); - assert_eq!(e.status_code(), StatusCode::Internal); - } - - #[test] - fn test_tcp_bind_error() { - fn throw_std_error() -> StdResult { - Err(std::io::ErrorKind::NotFound.into()) - } - let e = throw_std_error() - .context(TcpBindSnafu { addr: "127.0.0.1" }) - .err() - .unwrap(); - assert!(e.backtrace_opt().is_some()); - assert_eq!(e.status_code(), StatusCode::Internal); - } - - #[test] - fn test_start_grpc_error() { - fn throw_tonic_error() -> StdResult { - tonic::transport::Endpoint::new("http//http").map(|_| ()) - } - let e = throw_tonic_error().context(StartGrpcSnafu).err().unwrap(); - assert!(e.backtrace_opt().is_some()); - assert_eq!(e.status_code(), StatusCode::Internal); - } - - #[test] - fn test_empty_table_error() { - let e = throw_none_option() - .context(EmptyTableNameSnafu) - .err() - .unwrap(); - assert!(e.backtrace_opt().is_some()); - assert_eq!(e.status_code(), StatusCode::InvalidArguments); - } - - #[test] - fn test_invalid_lease_key_error() { - let e = throw_none_option() - .context(InvalidLeaseKeySnafu { key: "test" }) - .err() - .unwrap(); - assert!(e.backtrace_opt().is_some()); - assert_eq!(e.status_code(), StatusCode::InvalidArguments); - } - - #[test] - fn test_lease_key_fromutf8_test() { - fn throw_fromutf8_error() -> StdResult { - let sparkle_heart = vec![0, 159, 146, 150]; - String::from_utf8(sparkle_heart).map(|_| ()) - } - let e = throw_fromutf8_error() - .context(LeaseKeyFromUtf8Snafu) - .err() - .unwrap(); - assert!(e.backtrace_opt().is_some()); - assert_eq!(e.status_code(), StatusCode::Unexpected); - } - - #[test] - fn test_serialize_to_json_error() { - let e = throw_serde_json_error() - .context(SerializeToJsonSnafu { input: "" }) - .err() - .unwrap(); - assert!(e.backtrace_opt().is_some()); - assert_eq!(e.status_code(), StatusCode::Internal); - } - - #[test] - fn test_deserialize_from_json_error() { - let e = throw_serde_json_error() - .context(DeserializeFromJsonSnafu { input: "" }) - .err() - .unwrap(); - assert!(e.backtrace_opt().is_some()); - assert_eq!(e.status_code(), StatusCode::Internal); - } - - #[test] - fn test_parse_num_error() { - fn throw_parse_int_error() -> StdResult { - "invalid num".parse::().map(|_| ()) - } - let e = throw_parse_int_error() - .context(ParseNumSnafu { err_msg: "" }) - .err() - .unwrap(); - assert!(e.backtrace_opt().is_some()); - assert_eq!(e.status_code(), StatusCode::InvalidArguments); - } - - #[test] - fn test_invalid_arguments_error() { - let e = throw_none_option() - .context(InvalidArgumentsSnafu { err_msg: "test" }) - .err() - .unwrap(); - assert!(e.backtrace_opt().is_some()); - assert_eq!(e.status_code(), StatusCode::InvalidArguments); - } - - #[test] - fn test_invalid_txn_error() { - let e = throw_none_option() - .context(InvalidTxnResultSnafu { err_msg: "test" }) - .err() - .unwrap(); - assert!(e.backtrace_opt().is_some()); - assert_eq!(e.status_code(), StatusCode::Unexpected); - } -} diff --git a/src/mito/src/error.rs b/src/mito/src/error.rs index a87b385206..4cf2ff8d7b 100644 --- a/src/mito/src/error.rs +++ b/src/mito/src/error.rs @@ -16,6 +16,7 @@ use std::any::Any; use common_error::ext::BoxedError; use common_error::prelude::*; +use snafu::Location; use store_api::storage::RegionNumber; use table::metadata::{TableInfoBuilderError, TableMetaBuilderError, TableVersion}; @@ -36,7 +37,7 @@ pub enum Error { BuildTableMeta { source: TableMetaBuilderError, table_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -47,16 +48,16 @@ pub enum Error { BuildTableInfo { source: TableInfoBuilderError, table_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Invalid primary key: {}", msg))] - InvalidPrimaryKey { msg: String, backtrace: Backtrace }, + InvalidPrimaryKey { msg: String, location: Location }, #[snafu(display("Missing timestamp index for table: {}", table_name))] MissingTimestampIndex { table_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -67,7 +68,7 @@ pub enum Error { BuildRowKeyDescriptor { source: store_api::storage::RowKeyDescriptorBuilderError, table_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -80,7 +81,7 @@ pub enum Error { source: store_api::storage::ColumnDescriptorBuilderError, table_name: String, column_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -91,7 +92,7 @@ pub enum Error { BuildColumnFamilyDescriptor { source: store_api::storage::ColumnFamilyDescriptorBuilderError, table_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -104,7 +105,7 @@ pub enum Error { source: store_api::storage::RegionDescriptorBuilderError, table_name: String, region_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -131,19 +132,19 @@ pub enum Error { #[snafu(display("Table info not found in manifest, table: {}", table_name))] TableInfoNotFound { - backtrace: Backtrace, + location: Location, table_name: String, }, #[snafu(display("Table already exists: {}", table_name))] TableExists { - backtrace: Backtrace, + location: Location, table_name: String, }, #[snafu(display("Table not found: {}", table_name))] TableNotFound { - backtrace: Backtrace, + location: Location, table_name: String, }, @@ -159,7 +160,7 @@ pub enum Error { column_qualified_name ))] ProjectedColumnNotFound { - backtrace: Backtrace, + location: Location, column_qualified_name: String, }, @@ -176,13 +177,13 @@ pub enum Error { RegionNotFound { table: String, region: RegionNumber, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Invalid region name: {}", region_name))] InvalidRegionName { region_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Invalid schema, source: {}", source))] @@ -228,10 +229,6 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } @@ -242,25 +239,3 @@ impl From for common_procedure::Error { common_procedure::Error::from_error_ext(e) } } - -#[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()); - } -} diff --git a/src/partition/src/error.rs b/src/partition/src/error.rs index f93478f3ed..b1511c6b87 100644 --- a/src/partition/src/error.rs +++ b/src/partition/src/error.rs @@ -17,17 +17,14 @@ use std::any::Any; use common_error::prelude::*; use common_query::prelude::Expr; use datafusion_common::ScalarValue; -use snafu::Snafu; +use snafu::{Location, Snafu}; use store_api::storage::RegionId; #[derive(Debug, Snafu)] #[snafu(visibility(pub))] pub enum Error { #[snafu(display("Failed to get meta info from cache, error: {}", err_msg))] - GetCache { - err_msg: String, - backtrace: Backtrace, - }, + GetCache { err_msg: String, location: Location }, #[snafu(display("Failed to request Meta, source: {}", source))] RequestMeta { @@ -39,13 +36,13 @@ pub enum Error { FindDatanode { table: String, region: RegionId, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to find table routes for table {}", table_name))] FindTableRoutes { table_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -56,51 +53,45 @@ pub enum Error { FindRegionRoutes { table_name: String, region_id: u64, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to serialize value to json, source: {}", source))] SerializeJson { source: serde_json::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to deserialize value from json, source: {}", source))] DeserializeJson { source: serde_json::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Expect {} region keys, actual {}", expect, actual))] RegionKeysSize { expect: usize, actual: usize, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to find region, reason: {}", reason))] - FindRegion { - reason: String, - backtrace: Backtrace, - }, + FindRegion { reason: String, location: Location }, #[snafu(display("Failed to find regions by filters: {:?}", filters))] FindRegions { filters: Vec, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to find partition column: {}", column_name))] FindPartitionColumn { column_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Invalid InsertRequest, reason: {}", reason))] - InvalidInsertRequest { - reason: String, - backtrace: Backtrace, - }, + InvalidInsertRequest { reason: String, location: Location }, #[snafu(display( "Invalid table route data in meta, table name: {}, msg: {}", @@ -110,7 +101,7 @@ pub enum Error { InvalidTableRouteData { table_name: String, err_msg: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -143,9 +134,6 @@ impl ErrorExt for Error { Error::FindDatanode { .. } => StatusCode::InvalidArguments, } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } fn as_any(&self) -> &dyn Any { self diff --git a/src/promql/src/error.rs b/src/promql/src/error.rs index 9de9a6490c..ab3f66a3ed 100644 --- a/src/promql/src/error.rs +++ b/src/promql/src/error.rs @@ -17,36 +17,37 @@ use std::any::Any; use common_error::prelude::*; use datafusion::error::DataFusionError; use promql_parser::parser::{Expr as PromExpr, TokenType}; +use snafu::Location; #[derive(Debug, Snafu)] #[snafu(visibility(pub))] pub enum Error { #[snafu(display("Unsupported expr type: {}", name))] - UnsupportedExpr { name: String, backtrace: Backtrace }, + UnsupportedExpr { name: String, location: Location }, #[snafu(display("Unexpected token: {:?}", token))] UnexpectedToken { token: TokenType, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Internal error during build DataFusion plan, error: {}", source))] DataFusionPlanning { source: datafusion::error::DataFusionError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Unexpected plan or expression: {}", desc))] - UnexpectedPlanExpr { desc: String, backtrace: Backtrace }, + UnexpectedPlanExpr { desc: String, location: Location }, #[snafu(display("Unknown table type, downcast failed"))] - UnknownTable { backtrace: Backtrace }, + UnknownTable { location: Location }, #[snafu(display("Cannot find time index column in table {}", table))] - TimeIndexNotFound { table: String, backtrace: Backtrace }, + TimeIndexNotFound { table: String, location: Location }, #[snafu(display("Cannot find value columns in table {}", table))] - ValueNotFound { table: String, backtrace: Backtrace }, + ValueNotFound { table: String, location: Location }, #[snafu(display("Cannot find the table {}", table))] TableNotFound { @@ -58,16 +59,10 @@ pub enum Error { "Cannot accept multiple vector as function input, PromQL expr: {:?}", expr ))] - MultipleVector { - expr: PromExpr, - backtrace: Backtrace, - }, + MultipleVector { expr: PromExpr, location: Location }, #[snafu(display("Expect a PromQL expr but not found, input expr: {:?}", expr))] - ExpectExpr { - expr: PromExpr, - backtrace: Backtrace, - }, + ExpectExpr { expr: PromExpr, location: Location }, #[snafu(display( "Illegal range: offset {}, length {}, array len {}", offset, @@ -78,16 +73,16 @@ pub enum Error { offset: u32, length: u32, len: usize, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Empty range is not expected"))] - EmptyRange { backtrace: Backtrace }, + EmptyRange { location: Location }, #[snafu(display( "Table (metric) name not found, this indicates a procedure error in PromQL planner" ))] - TableNameNotFound { backtrace: Backtrace }, + TableNameNotFound { location: Location }, #[snafu(display("General catalog error: {source}"))] Catalog { @@ -96,13 +91,13 @@ pub enum Error { }, #[snafu(display("Expect a range selector, but not found"))] - ExpectRangeSelector { backtrace: Backtrace }, + ExpectRangeSelector { location: Location }, #[snafu(display("Zero range in range selector"))] - ZeroRangeSelector { backtrace: Backtrace }, + ZeroRangeSelector { location: Location }, #[snafu(display("Cannot find column {col}"))] - ColumnNotFound { col: String, backtrace: Backtrace }, + ColumnNotFound { col: String, location: Location }, } impl ErrorExt for Error { @@ -130,9 +125,6 @@ impl ErrorExt for Error { Catalog { source } => source.status_code(), } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } fn as_any(&self) -> &dyn Any { self diff --git a/src/query/src/datafusion/error.rs b/src/query/src/datafusion/error.rs index 4edcb56a18..2f52ba8b4a 100644 --- a/src/query/src/datafusion/error.rs +++ b/src/query/src/datafusion/error.rs @@ -16,6 +16,7 @@ use std::any::Any; use common_error::prelude::*; use datafusion::error::DataFusionError; +use snafu::Location; /// Inner error of datafusion based query engine. #[derive(Debug, Snafu)] @@ -25,11 +26,11 @@ pub enum InnerError { Datafusion { msg: &'static str, source: DataFusionError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("PhysicalPlan downcast failed"))] - PhysicalPlanDowncast { backtrace: Backtrace }, + PhysicalPlanDowncast { location: Location }, #[snafu(display("Fail to convert arrow schema, source: {}", source))] ConvertSchema { @@ -75,39 +76,7 @@ impl ErrorExt for InnerError { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } } - -#[cfg(test)] -mod tests { - - use super::*; - - fn throw_df_error() -> Result<(), DataFusionError> { - Err(DataFusionError::NotImplemented("test".to_string())) - } - - fn assert_error(err: &InnerError, code: StatusCode) { - assert_eq!(code, err.status_code()); - assert!(err.backtrace_opt().is_some()); - } - - #[test] - fn test_datafusion_as_source() { - let err = throw_df_error() - .context(DatafusionSnafu { msg: "test df" }) - .err() - .unwrap(); - assert_error(&err, StatusCode::EngineExecuteQuery); - - let res: Result<(), InnerError> = PhysicalPlanDowncastSnafu {}.fail(); - let err = res.err().unwrap(); - assert_error(&err, StatusCode::Unexpected); - } -} diff --git a/src/query/src/error.rs b/src/query/src/error.rs index fde14f2a4c..da2ecdf70e 100644 --- a/src/query/src/error.rs +++ b/src/query/src/error.rs @@ -16,13 +16,13 @@ use std::any::Any; use common_error::prelude::*; use datafusion::error::DataFusionError; -use snafu::{Backtrace, ErrorCompat, Snafu}; +use snafu::{Location, Snafu}; #[derive(Debug, Snafu)] #[snafu(visibility(pub))] pub enum Error { #[snafu(display("Unsupported expr type: {}", name))] - UnsupportedExpr { name: String, backtrace: Backtrace }, + UnsupportedExpr { name: String, location: Location }, #[snafu(display("General catalog error: {}", source))] Catalog { @@ -31,19 +31,13 @@ pub enum Error { }, #[snafu(display("Catalog not found: {}", catalog))] - CatalogNotFound { - catalog: String, - backtrace: Backtrace, - }, + CatalogNotFound { catalog: String, location: Location }, #[snafu(display("Schema not found: {}", schema))] - SchemaNotFound { - schema: String, - backtrace: Backtrace, - }, + SchemaNotFound { schema: String, location: Location }, #[snafu(display("Table not found: {}", table))] - TableNotFound { table: String, backtrace: Backtrace }, + TableNotFound { table: String, location: Location }, #[snafu(display("Failed to do vector computation, source: {}", source))] VectorComputation { @@ -70,7 +64,7 @@ pub enum Error { QueryAccessDenied { catalog: String, schema: String }, #[snafu(display("The SQL string has multiple statements, query: {}", query))] - MultipleStatements { query: String, backtrace: Backtrace }, + MultipleStatements { query: String, location: Location }, #[snafu(display("Failed to convert Datafusion schema: {}", source))] ConvertDatafusionSchema { @@ -82,20 +76,20 @@ pub enum Error { ParseTimestamp { raw: String, source: chrono::ParseError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to parse float number `{}`: {}", raw, source))] ParseFloat { raw: String, source: std::num::ParseFloatError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("DataFusion error: {}", source))] DataFusion { source: DataFusionError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("General SQL error: {}", source))] @@ -108,13 +102,13 @@ pub enum Error { PlanSql { sql: String, source: DataFusionError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Timestamp column for table '{table_name}' is missing!"))] MissingTimestampColumn { table_name: String, - backtrace: Backtrace, + location: Location, }, } @@ -143,10 +137,6 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } diff --git a/src/script/src/error.rs b/src/script/src/error.rs index 2734f2c473..b9105bde93 100644 --- a/src/script/src/error.rs +++ b/src/script/src/error.rs @@ -16,7 +16,7 @@ use std::any::Any; use common_error::ext::ErrorExt; use common_error::prelude::{Snafu, StatusCode}; -use snafu::{Backtrace, ErrorCompat}; +use snafu::Location; #[derive(Debug, Snafu)] #[snafu(visibility(pub))] @@ -34,7 +34,7 @@ pub enum Error { }, #[snafu(display("Scripts table not found"))] - ScriptsTableNotFound { backtrace: Backtrace }, + ScriptsTableNotFound { location: Location }, #[snafu(display( "Failed to insert script to scripts table, name: {}, source: {}", @@ -62,7 +62,7 @@ pub enum Error { }, #[snafu(display("Script not found, name: {}", name))] - ScriptNotFound { backtrace: Backtrace, name: String }, + ScriptNotFound { location: Location, name: String }, #[snafu(display("Failed to find script by name: {}", name))] FindScript { @@ -78,7 +78,7 @@ pub enum Error { }, #[snafu(display("Failed to cast type, msg: {}", msg))] - CastType { msg: String, backtrace: Backtrace }, + CastType { msg: String, location: Location }, } pub type Result = std::result::Result; @@ -98,45 +98,7 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } } - -#[cfg(test)] -mod tests { - use snafu::ResultExt; - - use super::*; - - fn throw_catalog_error() -> catalog::error::Result<()> { - catalog::error::IllegalManagerStateSnafu { msg: "test" }.fail() - } - - fn throw_python_error() -> crate::python::error::Result<()> { - crate::python::error::CoprParseSnafu { - reason: "test", - loc: None, - } - .fail() - } - - #[test] - fn test_error() { - let err = throw_catalog_error() - .context(FindScriptsTableSnafu) - .unwrap_err(); - assert_eq!(StatusCode::Unexpected, err.status_code()); - assert!(err.backtrace_opt().is_some()); - - let err = throw_python_error() - .context(ExecutePythonSnafu { name: "test" }) - .unwrap_err(); - assert_eq!(StatusCode::InvalidArguments, err.status_code()); - assert!(err.backtrace_opt().is_some()); - } -} diff --git a/src/script/src/python/error.rs b/src/script/src/python/error.rs index 5fa21a3230..e55869bdea 100644 --- a/src/script/src/python/error.rs +++ b/src/script/src/python/error.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use common_error::prelude::{ErrorCompat, ErrorExt, StatusCode}; +use common_error::prelude::{ErrorExt, StatusCode}; use console::{style, Style}; use datafusion::error::DataFusionError; use datatypes::arrow::error::ArrowError; @@ -23,7 +23,7 @@ use rustpython_parser::ast::Location; use rustpython_parser::error::ParseError; pub use snafu::ensure; use snafu::prelude::Snafu; -use snafu::Backtrace; +use snafu::Location as SnafuLocation; pub type Result = std::result::Result; pub(crate) fn ret_other_error_with(reason: String) -> OtherSnafu { @@ -47,29 +47,32 @@ pub enum Error { #[snafu(display("Failed to parse script, source: {}", source))] PyParse { - backtrace: Backtrace, + location: SnafuLocation, source: ParseError, }, #[snafu(display("Failed to compile script, source: {}", source))] PyCompile { - backtrace: Backtrace, + location: SnafuLocation, source: CodegenError, }, /// rustpython problem, using python virtual machines' backtrace instead #[snafu(display("Python Runtime error, error: {}", msg))] - PyRuntime { msg: String, backtrace: Backtrace }, + PyRuntime { + msg: String, + location: SnafuLocation, + }, #[snafu(display("Arrow error: {}", source))] Arrow { - backtrace: Backtrace, + location: SnafuLocation, source: ArrowError, }, #[snafu(display("DataFusion error: {}", source))] DataFusion { - backtrace: Backtrace, + location: SnafuLocation, source: DataFusionError, }, @@ -81,7 +84,7 @@ pub enum Error { "".into() }))] CoprParse { - backtrace: Backtrace, + location: SnafuLocation, reason: String, // location is option because maybe errors can't give a clear location? loc: Option, @@ -90,15 +93,18 @@ pub enum Error { /// Other types of error that isn't any of above #[snafu(display("Coprocessor's Internal error: {}", reason))] Other { - backtrace: Backtrace, + location: SnafuLocation, reason: String, }, #[snafu(display("Unsupported sql in coprocessor: {}", sql))] - UnsupportedSql { sql: String, backtrace: Backtrace }, + UnsupportedSql { + sql: String, + location: SnafuLocation, + }, #[snafu(display("Missing sql in coprocessor"))] - MissingSql { backtrace: Backtrace }, + MissingSql { location: SnafuLocation }, #[snafu(display("Failed to retrieve record batches, source: {}", source))] RecordBatch { @@ -140,9 +146,6 @@ impl ErrorExt for Error { | Error::MissingSql { .. } => StatusCode::InvalidArguments, } } - fn backtrace_opt(&self) -> Option<&common_error::snafu::Backtrace> { - ErrorCompat::backtrace(self) - } fn as_any(&self) -> &dyn std::any::Any { self @@ -224,24 +227,3 @@ pub fn get_error_reason_loc(err: &Error) -> (String, Option) { _ => (format!("Unknown error: {err:?}"), None), } } - -#[cfg(test)] -mod tests { - use snafu::ResultExt; - - use super::*; - - fn throw_query_error() -> query::error::Result<()> { - query::error::TableNotFoundSnafu { - table: String::new(), - } - .fail() - } - - #[test] - fn test_error() { - let err = throw_query_error().context(DatabaseQuerySnafu).unwrap_err(); - assert_eq!(StatusCode::InvalidArguments, err.status_code()); - assert!(err.backtrace_opt().is_some()); - } -} diff --git a/src/script/src/python/pyo3/copr_impl.rs b/src/script/src/python/pyo3/copr_impl.rs index 3b86cc16c4..93ad7d775b 100644 --- a/src/script/src/python/pyo3/copr_impl.rs +++ b/src/script/src/python/pyo3/copr_impl.rs @@ -22,7 +22,7 @@ use datatypes::vectors::{Helper, VectorRef}; use pyo3::exceptions::{PyRuntimeError, PyValueError}; use pyo3::types::{PyBool, PyDict, PyFloat, PyInt, PyList, PyModule, PyString, PyTuple}; use pyo3::{pymethods, PyAny, PyCell, PyObject, PyResult, Python, ToPyObject}; -use snafu::{ensure, Backtrace, GenerateImplicitData, ResultExt}; +use snafu::{ensure, Location, ResultExt}; use crate::python::error::{self, NewRecordBatchSnafu, OtherSnafu, Result}; use crate::python::ffi_types::copr::PyQueryEngine; @@ -149,7 +149,7 @@ coprocessor = copr })() .map_err(|err| error::Error::PyRuntime { msg: err.into_value(py).to_string(), - backtrace: Backtrace::generate(), + location: snafu::location!(), })?; ensure!( cols.len() == copr.deco_args.ret_names.len(), diff --git a/src/script/src/python/rspython/test.rs b/src/script/src/python/rspython/test.rs index 381c98b482..f82c037e69 100644 --- a/src/script/src/python/rspython/test.rs +++ b/src/script/src/python/rspython/test.rs @@ -255,7 +255,7 @@ def calc_rvs(open_time, close): .unwrap(); let ret = exec_coprocessor(python_source, &Some(rb)); if let Err(Error::PyParse { - backtrace: _, + location: _, source, }) = ret { @@ -305,7 +305,7 @@ def a(cpu, mem): .unwrap(); let ret = exec_coprocessor(python_source, &Some(rb)); if let Err(Error::PyParse { - backtrace: _, + location: _, source, }) = ret { diff --git a/src/script/src/python/rspython/utils.rs b/src/script/src/python/rspython/utils.rs index 24f34894a6..d169bf3eb0 100644 --- a/src/script/src/python/rspython/utils.rs +++ b/src/script/src/python/rspython/utils.rs @@ -23,7 +23,7 @@ use datatypes::vectors::{ }; use rustpython_vm::builtins::{PyBaseExceptionRef, PyBool, PyFloat, PyInt, PyList, PyStr}; use rustpython_vm::{PyObjectRef, PyPayload, PyResult, VirtualMachine}; -use snafu::{Backtrace, GenerateImplicitData, OptionExt, ResultExt}; +use snafu::{OptionExt, ResultExt}; use crate::python::error; use crate::python::error::ret_other_error_with; @@ -39,16 +39,13 @@ pub fn is_instance(obj: &PyObjectRef, vm: &VirtualMachine) -> bool pub fn format_py_error(excep: PyBaseExceptionRef, vm: &VirtualMachine) -> error::Error { let mut msg = String::new(); if let Err(e) = vm.write_exception(&mut msg, &excep) { - return error::Error::PyRuntime { + return error::PyRuntimeSnafu { msg: format!("Failed to write exception msg, err: {e}"), - backtrace: Backtrace::generate(), - }; + } + .build(); } - error::Error::PyRuntime { - msg, - backtrace: Backtrace::generate(), - } + error::PyRuntimeSnafu { msg }.build() } pub(crate) fn py_obj_to_value(obj: &PyObjectRef, vm: &VirtualMachine) -> PyResult { diff --git a/src/script/src/python/utils.rs b/src/script/src/python/utils.rs index 4ef69d3c0e..beeac92923 100644 --- a/src/script/src/python/utils.rs +++ b/src/script/src/python/utils.rs @@ -16,7 +16,6 @@ use futures::Future; use once_cell::sync::OnceCell; use rustpython_vm::builtins::PyBaseExceptionRef; use rustpython_vm::{PyObjectRef, PyPayload, VirtualMachine}; -use snafu::{Backtrace, GenerateImplicitData}; use tokio::runtime::Runtime; use crate::python::error; @@ -30,16 +29,12 @@ pub fn is_instance(obj: &PyObjectRef, vm: &VirtualMachine) -> bool pub fn format_py_error(excep: PyBaseExceptionRef, vm: &VirtualMachine) -> error::Error { let mut msg = String::new(); if let Err(e) = vm.write_exception(&mut msg, &excep) { - return error::Error::PyRuntime { + return error::PyRuntimeSnafu { msg: format!("Failed to write exception msg, err: {e}"), - backtrace: Backtrace::generate(), - }; - } - - error::Error::PyRuntime { - msg, - backtrace: Backtrace::generate(), + } + .build(); } + error::PyRuntimeSnafu { msg }.build() } static LOCAL_RUNTIME: OnceCell = OnceCell::new(); fn get_local_runtime() -> std::thread::Result<&'static Runtime> { diff --git a/src/servers/src/auth.rs b/src/servers/src/auth.rs index adff1a74d8..24fba17c23 100644 --- a/src/servers/src/auth.rs +++ b/src/servers/src/auth.rs @@ -18,7 +18,7 @@ use common_error::ext::BoxedError; use common_error::prelude::ErrorExt; use common_error::status_code::StatusCode; use session::context::UserInfo; -use snafu::{Backtrace, ErrorCompat, OptionExt, Snafu}; +use snafu::{Location, OptionExt, Snafu}; use crate::auth::user_provider::StaticUserProvider; @@ -91,7 +91,7 @@ pub enum Error { #[snafu(display("IO error, source: {}", source))] Io { source: std::io::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Auth failed, source: {}", source))] @@ -138,10 +138,6 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn std::any::Any { self } diff --git a/src/servers/src/error.rs b/src/servers/src/error.rs index b9ab4b5ab2..101ac1f44b 100644 --- a/src/servers/src/error.rs +++ b/src/servers/src/error.rs @@ -24,6 +24,7 @@ use catalog; use common_error::prelude::*; use query::parser::PromQuery; use serde_json::json; +use snafu::Location; use tonic::codegen::http::{HeaderMap, HeaderValue}; use tonic::metadata::MetadataMap; use tonic::Code; @@ -58,10 +59,7 @@ pub enum Error { StartGrpc { source: tonic::transport::Error }, #[snafu(display("{} server is already started", server))] - AlreadyStarted { - server: String, - backtrace: Backtrace, - }, + AlreadyStarted { server: String, location: Location }, #[snafu(display("Failed to bind address {}, source: {}", addr, source))] TcpBind { @@ -122,10 +120,7 @@ pub enum Error { NotSupported { feat: String }, #[snafu(display("Invalid query: {}", reason))] - InvalidQuery { - reason: String, - backtrace: Backtrace, - }, + InvalidQuery { reason: String, location: Location }, #[snafu(display("Failed to parse InfluxDB line protocol, source: {}", source))] InfluxdbLineProtocol { @@ -140,10 +135,10 @@ pub enum Error { }, #[snafu(display("Failed to convert time precision, name: {}", name))] - TimePrecision { name: String, backtrace: Backtrace }, + TimePrecision { name: String, location: Location }, #[snafu(display("Connection reset by peer"))] - ConnResetByPeer { backtrace: Backtrace }, + ConnResetByPeer { location: Location }, #[snafu(display("Hyper error, source: {}", source))] Hyper { source: hyper::Error }, @@ -151,13 +146,13 @@ pub enum Error { #[snafu(display("Invalid OpenTSDB line, source: {}", source))] InvalidOpentsdbLine { source: FromUtf8Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Invalid OpenTSDB Json request, source: {}", source))] InvalidOpentsdbJsonRequest { source: serde_json::error::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -173,26 +168,26 @@ pub enum Error { #[snafu(display("Failed to decode prometheus remote request, source: {}", source))] DecodePromRemoteRequest { - backtrace: Backtrace, + location: Location, source: prost::DecodeError, }, #[snafu(display("Failed to decompress prometheus remote request, source: {}", source))] DecompressPromRemoteRequest { - backtrace: Backtrace, + location: Location, source: snap::Error, }, #[snafu(display("Invalid prometheus remote request, msg: {}", msg))] - InvalidPromRemoteRequest { msg: String, backtrace: Backtrace }, + InvalidPromRemoteRequest { msg: String, location: Location }, #[snafu(display("Invalid prometheus remote read query result, msg: {}", msg))] - InvalidPromRemoteReadQueryResult { msg: String, backtrace: Backtrace }, + InvalidPromRemoteReadQueryResult { msg: String, location: Location }, #[snafu(display("Invalid Flight ticket, source: {}", source))] InvalidFlightTicket { source: api::DecodeError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to start frontend service, source: {}", source))] @@ -202,10 +197,7 @@ pub enum Error { }, #[snafu(display("Failed to build context, msg: {}", err_msg))] - BuildingContext { - err_msg: String, - backtrace: Backtrace, - }, + BuildingContext { err_msg: String, location: Location }, #[snafu(display("Tls is required for {}, plain connection is rejected", server))] TlsRequired { server: String }, @@ -225,25 +217,25 @@ pub enum Error { #[snafu(display("Invalid visibility ASCII chars, source: {}", source))] InvisibleASCII { source: hyper::header::ToStrError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Unsupported http auth scheme, name: {}", name))] UnsupportedAuthScheme { name: String }, #[snafu(display("Invalid http authorization header"))] - InvalidAuthorizationHeader { backtrace: Backtrace }, + InvalidAuthorizationHeader { location: Location }, #[snafu(display("Invalid base64 value, source: {:?}", source))] InvalidBase64Value { source: DecodeError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Invalid utf-8 value, source: {:?}", source))] InvalidUtf8Value { source: FromUtf8Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Error accessing catalog: {}", source))] @@ -274,13 +266,13 @@ pub enum Error { #[snafu(display("Failed to build gRPC reflection service, source: {}", source))] GrpcReflectionService { source: tonic_reflection::server::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to build HTTP response, source: {source}"))] BuildHttpResponse { source: http::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to parse PromQL: {query:?}, source: {source}"))] @@ -359,10 +351,6 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } diff --git a/src/sql/src/error.rs b/src/sql/src/error.rs index b9c72e7280..37da1fd401 100644 --- a/src/sql/src/error.rs +++ b/src/sql/src/error.rs @@ -18,6 +18,7 @@ use common_error::prelude::*; use common_time::timestamp::TimeUnit; use common_time::Timestamp; use datatypes::prelude::ConcreteDataType; +use snafu::Location; use sqlparser::parser::ParserError; use sqlparser::tokenizer::TokenizerError; @@ -142,7 +143,7 @@ pub enum Error { #[snafu(display("Unable to convert statement {} to DataFusion statement", statement))] ConvertToDfStatement { statement: String, - backtrace: Backtrace, + location: Location, }, } @@ -177,10 +178,6 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } diff --git a/src/storage/src/error.rs b/src/storage/src/error.rs index 6148dc4999..b297d283cc 100644 --- a/src/storage/src/error.rs +++ b/src/storage/src/error.rs @@ -21,6 +21,7 @@ use common_runtime::error::Error as RuntimeError; use datatypes::arrow::error::ArrowError; use datatypes::prelude::ConcreteDataType; use serde_json::error::Error as JsonError; +use snafu::Location; use store_api::manifest::action::ProtocolVersion; use store_api::manifest::ManifestVersion; use store_api::storage::{RegionId, SequenceNumber}; @@ -40,66 +41,63 @@ pub enum Error { }, #[snafu(display("Missing column {} in write batch", column))] - BatchMissingColumn { - column: String, - backtrace: Backtrace, - }, + BatchMissingColumn { column: String, location: Location }, #[snafu(display("Failed to write parquet file, source: {}", source))] WriteParquet { source: parquet::errors::ParquetError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to create RecordBatch from vectors, source: {}", source))] NewRecordBatch { - backtrace: Backtrace, + location: Location, source: ArrowError, }, #[snafu(display("Fail to read object from path: {}, source: {}", path, source))] ReadObject { path: String, - backtrace: Backtrace, + location: Location, source: object_store::Error, }, #[snafu(display("Fail to write object into path: {}, source: {}", path, source))] WriteObject { path: String, - backtrace: Backtrace, + location: Location, source: object_store::Error, }, #[snafu(display("Fail to delete object from path: {}, source: {}", path, source))] DeleteObject { path: String, - backtrace: Backtrace, + location: Location, source: object_store::Error, }, #[snafu(display("Fail to list objects in path: {}, source: {}", path, source))] ListObjects { path: String, - backtrace: Backtrace, + location: Location, source: object_store::Error, }, #[snafu(display("Fail to create str from bytes, source: {}", source))] Utf8 { - backtrace: Backtrace, + location: Location, source: Utf8Error, }, #[snafu(display("Fail to encode object into json , source: {}", source))] EncodeJson { - backtrace: Backtrace, + location: Location, source: JsonError, }, #[snafu(display("Fail to decode object from json , source: {}", source))] DecodeJson { - backtrace: Backtrace, + location: Location, source: JsonError, }, @@ -107,7 +105,7 @@ pub enum Error { InvalidScanIndex { start: ManifestVersion, end: ManifestVersion, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -123,24 +121,24 @@ pub enum Error { #[snafu(display("Failed to encode WAL header, source {}", source))] EncodeWalHeader { - backtrace: Backtrace, + location: Location, source: std::io::Error, }, #[snafu(display("Failed to decode WAL header, source {}", source))] DecodeWalHeader { - backtrace: Backtrace, + location: Location, source: std::io::Error, }, #[snafu(display("Failed to join task, source: {}", source))] JoinTask { source: common_runtime::JoinError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Task already cancelled"))] - Cancelled { backtrace: Backtrace }, + Cancelled { location: Location }, #[snafu(display("Failed to cancel flush, source: {}", source))] CancelFlush { @@ -156,7 +154,7 @@ pub enum Error { ManifestProtocolForbidRead { min_version: ProtocolVersion, supported_version: ProtocolVersion, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -167,11 +165,11 @@ pub enum Error { ManifestProtocolForbidWrite { min_version: ProtocolVersion, supported_version: ProtocolVersion, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to decode action list, {}", msg))] - DecodeMetaActionList { msg: String, backtrace: Backtrace }, + DecodeMetaActionList { msg: String, location: Location }, #[snafu(display("Failed to read line, err: {}", source))] Readline { source: IoError }, @@ -180,13 +178,13 @@ pub enum Error { ReadParquet { file: String, source: parquet::errors::ParquetError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Region is under {} state, cannot proceed operation", state))] InvalidRegionState { state: &'static str, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to read WAL, region_id: {}, source: {}", region_id, source))] @@ -211,7 +209,7 @@ pub enum Error { WalDataCorrupted { region_id: RegionId, message: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -222,7 +220,7 @@ pub enum Error { SequenceNotMonotonic { prev: SequenceNumber, given: SequenceNumber, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to convert store schema, file: {}, source: {}", file, source))] @@ -240,7 +238,7 @@ pub enum Error { }, #[snafu(display("Try to write the closed region"))] - ClosedRegion { backtrace: Backtrace }, + ClosedRegion { location: Location }, #[snafu(display("Invalid projection, source: {}", source))] InvalidProjection { @@ -255,7 +253,7 @@ pub enum Error { }, #[snafu(display("Failed to build batch, {}", msg))] - BuildBatch { msg: String, backtrace: Backtrace }, + BuildBatch { msg: String, location: Location }, #[snafu(display("Failed to filter column {}, source: {}", name, source))] FilterColumn { @@ -296,21 +294,18 @@ pub enum Error { /// Schema version of data to write. data_version: u32, schema_version: u32, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Column {} not in schema with version {}", column, version))] NotInSchemaToCompat { column: String, version: u32, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Incompatible schema to read, reason: {}", reason))] - CompatRead { - reason: String, - backtrace: Backtrace, - }, + CompatRead { reason: String, location: Location }, #[snafu(display( "Failed to read column {}, could not create default value, source: {}", @@ -324,10 +319,7 @@ pub enum Error { }, #[snafu(display("Failed to read column {}, no proper default value for it", column))] - NoDefaultToRead { - column: String, - backtrace: Backtrace, - }, + NoDefaultToRead { column: String, location: Location }, #[snafu(display( "Failed to convert arrow chunk to batch, name: {}, source: {}", @@ -341,7 +333,7 @@ pub enum Error { }, #[snafu(display("Unknown column {}", name))] - UnknownColumn { name: String, backtrace: Backtrace }, + UnknownColumn { name: String, location: Location }, #[snafu(display("Failed to create record batch for write batch, source:{}", source))] CreateRecordBatch { @@ -354,10 +346,7 @@ pub enum Error { write_batch::MAX_BATCH_SIZE, num_rows ))] - RequestTooLarge { - num_rows: usize, - backtrace: Backtrace, - }, + RequestTooLarge { num_rows: usize, location: Location }, #[snafu(display( "Type of column {} does not match type in schema, expect {:?}, given {:?}", @@ -369,11 +358,11 @@ pub enum Error { name: String, expect: ConcreteDataType, given: ConcreteDataType, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Column {} is not null but input has null", name))] - HasNull { name: String, backtrace: Backtrace }, + HasNull { name: String, location: Location }, #[snafu(display( "Length of column {} not equals to other columns, expect {}, given {}", @@ -385,44 +374,41 @@ pub enum Error { name: String, expect: usize, given: usize, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to decode write batch, corrupted data {}", message))] - BatchCorrupted { - message: String, - backtrace: Backtrace, - }, + BatchCorrupted { message: String, location: Location }, #[snafu(display("Failed to decode arrow data, source: {}", source))] DecodeArrow { - backtrace: Backtrace, + location: Location, source: ArrowError, }, #[snafu(display("Failed to encode arrow data, source: {}", source))] EncodeArrow { - backtrace: Backtrace, + location: Location, source: ArrowError, }, #[snafu(display("Failed to parse schema, source: {}", source))] ParseSchema { - backtrace: Backtrace, + location: Location, source: datatypes::error::Error, }, #[snafu(display("More columns than expected in the request"))] - MoreColumnThanExpected { backtrace: Backtrace }, + MoreColumnThanExpected { location: Location }, #[snafu(display("Failed to decode parquet file time range, msg: {}", msg))] - DecodeParquetTimeRange { msg: String, backtrace: Backtrace }, + DecodeParquetTimeRange { msg: String, location: Location }, #[snafu(display("Scheduler rate limited, msg: {}", msg))] RateLimited { msg: String }, #[snafu(display("Cannot schedule request, scheduler's already stopped"))] - IllegalSchedulerState { backtrace: Backtrace }, + IllegalSchedulerState { location: Location }, #[snafu(display("Failed to start manifest gc task: {}", source))] StartManifestGcTask { @@ -439,13 +425,13 @@ pub enum Error { #[snafu(display("Failed to stop scheduler, source: {}", source))] StopScheduler { source: JoinError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to delete SST file, source: {}", source))] DeleteSst { source: object_store::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to calculate SST expire time, source: {}", source))] @@ -455,7 +441,7 @@ pub enum Error { }, #[snafu(display("Failed to create a checkpoint: {}", msg))] - ManifestCheckpoint { msg: String, backtrace: Backtrace }, + ManifestCheckpoint { msg: String, location: Location }, #[snafu(display("The compaction task is cancelled, region_id: {}", region_id))] CompactTaskCancel { @@ -546,51 +532,7 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } } - -#[cfg(test)] -mod tests { - use common_error::prelude::StatusCode::*; - use snafu::GenerateImplicitData; - - use super::*; - - fn throw_metadata_error() -> std::result::Result<(), MetadataError> { - Err(MetadataError::CfIdExists { - id: 1, - backtrace: Backtrace::generate(), - }) - } - - #[test] - fn test_invalid_region_desc_error() { - let err = throw_metadata_error() - .context(InvalidRegionDescSnafu { region: "hello" }) - .err() - .unwrap(); - - assert_eq!(StatusCode::InvalidArguments, err.status_code()); - assert!(err.backtrace_opt().is_some()); - } - - #[test] - pub fn test_arrow_error() { - fn throw_arrow_error() -> std::result::Result<(), ArrowError> { - Err(ArrowError::IoError("Lorem ipsum".to_string())) - } - - let error = throw_arrow_error() - .context(NewRecordBatchSnafu) - .err() - .unwrap(); - assert_eq!(Unexpected, error.status_code()); - assert!(error.backtrace_opt().is_some()); - } -} diff --git a/src/storage/src/metadata.rs b/src/storage/src/metadata.rs index f4f172f2d2..08d25d29ee 100644 --- a/src/storage/src/metadata.rs +++ b/src/storage/src/metadata.rs @@ -21,7 +21,7 @@ use common_error::prelude::*; use datatypes::data_type::ConcreteDataType; use datatypes::schema::{ColumnSchema, Metadata}; use serde::{Deserialize, Serialize}; -use snafu::{ensure, OptionExt}; +use snafu::{ensure, Location, OptionExt}; use store_api::storage::consts::{self, ReservedColumnId}; use store_api::storage::{ AddColumn, AlterOperation, AlterRequest, ColumnDescriptor, ColumnDescriptorBuilder, @@ -38,16 +38,16 @@ use crate::schema::{RegionSchema, RegionSchemaRef}; #[snafu(visibility(pub(crate)))] pub enum Error { #[snafu(display("Column name {} already exists", name))] - ColNameExists { name: String, backtrace: Backtrace }, + ColNameExists { name: String, location: Location }, #[snafu(display("Column family name {} already exists", name))] - CfNameExists { name: String, backtrace: Backtrace }, + CfNameExists { name: String, location: Location }, #[snafu(display("Column family id {} already exists", id))] - CfIdExists { id: ColumnId, backtrace: Backtrace }, + CfIdExists { id: ColumnId, location: Location }, #[snafu(display("Column id {} already exists", id))] - ColIdExists { id: ColumnId, backtrace: Backtrace }, + ColIdExists { id: ColumnId, location: Location }, #[snafu(display("Failed to build schema, source: {}", source))] InvalidSchema { @@ -56,10 +56,10 @@ pub enum Error { }, #[snafu(display("Column name {} is reserved by the system", name))] - ReservedColumn { name: String, backtrace: Backtrace }, + ReservedColumn { name: String, location: Location }, #[snafu(display("Missing timestamp key column"))] - MissingTimestamp { backtrace: Backtrace }, + MissingTimestamp { location: Location }, // Variants for validating `AlterRequest`, which won't have a backtrace. #[snafu(display("Expect altering metadata with version {}, given {}", expect, given))] @@ -99,16 +99,16 @@ pub enum Error { // Store key and value in one string to reduce the enum size. key_value: String, source: std::num::ParseIntError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Metadata of {} not found", key))] - MetaNotFound { key: String, backtrace: Backtrace }, + MetaNotFound { key: String, location: Location }, #[snafu(display("Failed to build column descriptor, source: {}", source))] BuildColumnDescriptor { source: ColumnDescriptorBuilderError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to convert from arrow schema, source: {}", source))] @@ -118,7 +118,7 @@ pub enum Error { }, #[snafu(display("Invalid internal column index in arrow schema"))] - InvalidIndex { backtrace: Backtrace }, + InvalidIndex { location: Location }, #[snafu(display( "Failed to convert arrow chunk to batch, name: {}, source: {}", @@ -138,7 +138,7 @@ pub enum Error { }, #[snafu(display("Invalid projection, {}", msg))] - InvalidProjection { msg: String, backtrace: Backtrace }, + InvalidProjection { msg: String, location: Location }, } pub type Result = std::result::Result; @@ -148,10 +148,6 @@ impl ErrorExt for Error { StatusCode::InvalidArguments } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn std::any::Any { self } diff --git a/src/storage/src/write_batch.rs b/src/storage/src/write_batch.rs index 1cfbebf898..4ec287d22a 100644 --- a/src/storage/src/write_batch.rs +++ b/src/storage/src/write_batch.rs @@ -413,7 +413,6 @@ mod tests { fn check_err(err: Error, msg: &str) { assert_eq!(StatusCode::InvalidArguments, err.status_code()); - assert!(err.backtrace_opt().is_some()); assert!( err.to_string().contains(msg), "<{err}> does not contain {msg}", diff --git a/src/store-api/src/logstore/entry_stream.rs b/src/store-api/src/logstore/entry_stream.rs index 2bd5f32e64..c8e675a601 100644 --- a/src/store-api/src/logstore/entry_stream.rs +++ b/src/store-api/src/logstore/entry_stream.rs @@ -44,7 +44,6 @@ mod tests { } use common_error::prelude::{ErrorExt, Snafu}; - use snafu::{Backtrace, ErrorCompat}; #[derive(Debug, Snafu)] #[snafu(visibility(pub))] @@ -60,10 +59,6 @@ mod tests { } impl ErrorExt for Error { - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } diff --git a/src/table-procedure/src/error.rs b/src/table-procedure/src/error.rs index 371c81fa9c..84bc49a542 100644 --- a/src/table-procedure/src/error.rs +++ b/src/table-procedure/src/error.rs @@ -16,6 +16,7 @@ use std::any::Any; use common_error::prelude::*; use common_procedure::ProcedureId; +use snafu::Location; #[derive(Debug, Snafu)] #[snafu(visibility(pub(crate)))] @@ -23,13 +24,13 @@ pub enum Error { #[snafu(display("Failed to serialize procedure to json, source: {}", source))] SerializeProcedure { source: serde_json::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to deserialize procedure from json, source: {}", source))] DeserializeProcedure { source: serde_json::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Invalid raw schema, source: {}", source))] @@ -53,7 +54,7 @@ pub enum Error { #[snafu(display("Subprocedure {} failed", subprocedure_id))] SubprocedureFailed { subprocedure_id: ProcedureId, - backtrace: Backtrace, + location: Location, }, } @@ -73,10 +74,6 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } diff --git a/src/table/src/error.rs b/src/table/src/error.rs index e2fbe0b2c6..d9ac4d13d1 100644 --- a/src/table/src/error.rs +++ b/src/table/src/error.rs @@ -18,6 +18,7 @@ use common_error::prelude::*; use common_recordbatch::error::Error as RecordBatchError; use datafusion::error::DataFusionError; use datatypes::arrow::error::ArrowError; +use snafu::Location; pub type Result = std::result::Result; @@ -28,37 +29,31 @@ pub enum Error { #[snafu(display("Datafusion error: {}", source))] Datafusion { source: DataFusionError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Poll stream failed, source: {}", source))] PollStream { source: ArrowError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to convert Arrow schema, source: {}", source))] SchemaConversion { source: datatypes::error::Error, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Engine not found: {}", engine))] - EngineNotFound { - engine: String, - backtrace: Backtrace, - }, + EngineNotFound { engine: String, location: Location }, #[snafu(display("Engine exist: {}", engine))] - EngineExist { - engine: String, - backtrace: Backtrace, - }, + EngineExist { engine: String, location: Location }, #[snafu(display("Table projection error, source: {}", source))] TableProjection { source: ArrowError, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to create record batch for Tables, source: {}", source))] @@ -71,7 +66,7 @@ pub enum Error { ColumnExists { column_name: String, table_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Failed to build schema, msg: {}, source: {}", msg, source))] @@ -85,7 +80,7 @@ pub enum Error { ColumnNotExists { column_name: String, table_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -96,7 +91,7 @@ pub enum Error { RemoveColumnInIndex { column_name: String, table_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display( @@ -109,10 +104,10 @@ pub enum Error { source: store_api::storage::ColumnDescriptorBuilderError, table_name: String, column_name: String, - backtrace: Backtrace, + location: Location, }, #[snafu(display("Regions schemas mismatch in table: {}", table))] - RegionSchemaMismatch { table: String, backtrace: Backtrace }, + RegionSchemaMismatch { table: String, location: Location }, #[snafu(display("Failed to operate table, source: {}", source))] TableOperation { source: BoxedError }, @@ -124,7 +119,7 @@ pub enum Error { ParseTableOption { key: String, value: String, - backtrace: Backtrace, + location: Location, }, } @@ -151,10 +146,6 @@ impl ErrorExt for Error { } } - fn backtrace_opt(&self) -> Option<&Backtrace> { - ErrorCompat::backtrace(self) - } - fn as_any(&self) -> &dyn Any { self } @@ -173,58 +164,3 @@ impl From for RecordBatchError { } } } - -#[cfg(test)] -mod tests { - use super::*; - - fn throw_df_error() -> Result<()> { - Err(DataFusionError::NotImplemented("table test".to_string())).context(DatafusionSnafu)? - } - - fn throw_column_exists_inner() -> std::result::Result<(), Error> { - ColumnExistsSnafu { - column_name: "col", - table_name: "test", - } - .fail() - } - - fn throw_missing_column() -> Result<()> { - throw_column_exists_inner() - } - - fn throw_arrow() -> Result<()> { - Err(ArrowError::ComputeError("Overflow".to_string())).context(PollStreamSnafu)? - } - - #[test] - fn test_error() { - let err = throw_df_error().err().unwrap(); - assert!(err.backtrace_opt().is_some()); - assert_eq!(StatusCode::EngineExecuteQuery, err.status_code()); - - let err = throw_missing_column().err().unwrap(); - assert!(err.backtrace_opt().is_some()); - assert_eq!(StatusCode::TableColumnExists, 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_column_exists_inner().err().unwrap(); - let err: RecordBatchError = err.into(); - assert!(err.backtrace_opt().is_some()); - assert_eq!(StatusCode::TableColumnExists, err.status_code()); - } - - #[test] - fn test_into_df_error() { - let err = throw_column_exists_inner().err().unwrap(); - let err: DataFusionError = err.into(); - assert!(matches!(err, DataFusionError::External(_))); - } -}