mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-05-18 05:50:41 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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}",
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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(_)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user