refactor(error): remove backtrace, and introduce call-site location for debugging (#1329)

* wip: global replace

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

* fix compile

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

* fix warnings

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

* remove unneeded tests of errors

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

* fix ErrorExt trait implementator

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

* fix warnings

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

* fix format

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

* fix pyo3 tests

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

---------

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
This commit is contained in:
Ruihang Xia
2023-04-06 12:06:00 +08:00
committed by GitHub
parent d10de46e03
commit da66138e80
47 changed files with 513 additions and 1496 deletions

View File

@@ -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<T> = std::result::Result<T, Error>;
@@ -26,12 +26,12 @@ pub type Result<T> = std::result::Result<T, Error>;
#[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

View File

@@ -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<u8>,
backtrace: Backtrace,
location: Location,
},
#[snafu(display("Invalid system catalog key: {:?}", key))]
InvalidKey {
key: Option<String>,
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<T> = std::result::Result<T, Error>;
@@ -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 {

View File

@@ -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());
}

View File

@@ -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
}

View File

@@ -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<E> = std::result::Result<(), E>;
#[test]
fn test_start_node_error() {
fn throw_datanode_error() -> StdResult<datanode::error::Error> {
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::Error> {
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::Error> {
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<std::io::Error> {
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);
}
}

View File

@@ -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<T> = std::result::Result<T, Error>;
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<common_error::snafu::Location> {
match self {
Error::Overflow { location, .. } => Some(*location),
Error::Underflow { location, .. } => Some(*location),
Error::Eof { location, .. } => Some(*location),
}
}
}
macro_rules! impl_read_le {

View File

@@ -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
}

View File

@@ -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<common_error::snafu::Location> {
match self {
Error::BuildBackend { location, .. } => Some(*location),
Error::ListObjects { location, .. } => Some(*location),
Error::UnsupportedBackendProtocol { .. }
| Error::EmptyHostPath { .. }
| Error::InvalidPath { .. }
| Error::InvalidUrl { .. }
| Error::InvalidConnection { .. } => None,
}
}
}

View File

@@ -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<crate::snafu::Location> {
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<crate::snafu::Location> {
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<crate::snafu::Location> {
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::<MockError>().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::<MockError>().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::<MockError>().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());
}
}

View File

@@ -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<Location> {
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<Location> {
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<Location> {
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"));
}
}

View File

@@ -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<Backtrace>,
source: Option<Box<MockError>>,
}
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<Location> {
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());
}
}

View File

@@ -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

View File

@@ -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<T> = std::result::Result<T, Error>;
@@ -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<E> = std::result::Result<(), E>;
fn throw_none_option() -> Option<String> {
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::Error> {
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);
}
}

View File

@@ -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<T> = std::result::Result<T, Error>;
@@ -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
}

View File

@@ -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<Error>,
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
}

View File

@@ -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<ConcreteDataType>,
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<T> = std::result::Result<T, Error>;
@@ -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<BoxedError> 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::<Error>().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::<i32>.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<i32, common_recordbatch::error::Error> =
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());
}
}

View File

@@ -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<T> = std::result::Result<T, Error>;
@@ -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
}

View File

@@ -15,6 +15,7 @@
use std::any::Any;
use common_error::prelude::*;
use snafu::Location;
use tokio::task::JoinError;
pub type Result<T> = std::result::Result<T, Error>;
@@ -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<common_error::snafu::Location> {
match self {
Error::BuildRuntime { location, .. }
| Error::IllegalState { location, .. }
| Error::WaitGcTaskStop { location, .. } => Some(*location),
}
}
}

View File

@@ -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
}

View File

@@ -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");
}

View File

@@ -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<common_error::snafu::Location> {
match self {
Error::ParseTimestamp { location, .. }
| Error::TimestampOverflow { location, .. }
| Error::ArithmeticOverflow { location, .. } => Some(*location),
Error::ParseDateStr { .. } => None,
}
}
}
pub type Result<T> = std::result::Result<T, Error>;
#[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()
);
}
}

View File

@@ -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<ObjectStoreConfig>,
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<Error> 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::<Error>().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")

View File

@@ -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<T> = std::result::Result<T, Error>;
#[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());
}
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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<T> = std::result::Result<T, Error>;
impl ErrorExt for Error {
fn backtrace_opt(&self) -> Option<&Backtrace> {
ErrorCompat::backtrace(self)
}
fn as_any(&self) -> &dyn std::any::Any {
self
}

View File

@@ -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<Error> 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<E> = std::result::Result<(), E>;
fn throw_none_option() -> Option<String> {
None
}
fn throw_etcd_client_error() -> StdResult<etcd_client::Error> {
Err(etcd_client::Error::InvalidArgs("".to_string()))
}
fn throw_serde_json_error() -> StdResult<serde_json::error::Error> {
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<std::io::Error> {
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::Error> {
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<std::string::FromUtf8Error> {
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<std::num::ParseIntError> {
"invalid num".parse::<i64>().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);
}
}

View File

@@ -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<Error> 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());
}
}

View File

@@ -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<Expr>,
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

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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
}

View File

@@ -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<T> = std::result::Result<T, Error>;
@@ -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());
}
}

View File

@@ -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<T> = std::result::Result<T, Error>;
pub(crate) fn ret_other_error_with(reason: String) -> OtherSnafu<String> {
@@ -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<Location>,
@@ -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<Location>) {
_ => (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());
}
}

View File

@@ -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(),

View File

@@ -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
{

View File

@@ -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<T: PyPayload>(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<Value> {

View File

@@ -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<T: PyPayload>(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<tokio::runtime::Runtime> = OnceCell::new();
fn get_local_runtime() -> std::thread::Result<&'static Runtime> {

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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());
}
}

View File

@@ -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<T> = std::result::Result<T, Error>;
@@ -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
}

View File

@@ -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}",

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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<T> = std::result::Result<T, Error>;
@@ -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<Error> 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(_)));
}
}