diff --git a/Cargo.lock b/Cargo.lock index 922e53caa6a0b..61549e402f440 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,6 +52,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "anyerror" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0eff878df53fcffe838345abfa5b3d7eeb87e856f53b7461e0e5d51fb9d045" +dependencies = [ + "backtrace", + "serde", + "serde_json", +] + [[package]] name = "anyhow" version = "1.0.52" @@ -2388,6 +2399,7 @@ dependencies = [ name = "databend-meta" version = "0.1.0" dependencies = [ + "anyerror", "anyhow", "async-raft", "async-trait", diff --git a/metasrv/Cargo.toml b/metasrv/Cargo.toml index e39434eb1967d..6a0b1a63e22d5 100644 --- a/metasrv/Cargo.toml +++ b/metasrv/Cargo.toml @@ -41,6 +41,7 @@ common-metrics = { path = "../common/metrics" } # Github dependencies # Crates.io dependencies +anyerror = "0.1.1" anyhow = "1.0.52" async-raft = { git = "https://github.com/datafuselabs/openraft", tag = "v0.6.2-alpha.14.1" } async-trait = "0.1.52" diff --git a/metasrv/src/any_error/any_error_impl.rs b/metasrv/src/any_error/any_error_impl.rs deleted file mode 100644 index eed1050543ef7..0000000000000 --- a/metasrv/src/any_error/any_error_impl.rs +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2021 Datafuse Labs. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::error::Error; -use std::fmt::Display; -use std::fmt::Formatter; - -use backtrace::Backtrace; -use serde::Deserialize; -use serde::Serialize; - -/// AnyError is a serializable wrapper `Error`. -/// -/// It is can be used to convert other `Error` into a serializable Error for transmission, -/// with most necessary info kept. -#[derive(Serialize, Deserialize, Clone, PartialEq, Default)] -pub struct AnyError { - typ: Option, - msg: String, - source: Option>, - backtrace: Option, -} - -impl Display for AnyError { - fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { - if let Some(t) = &self.typ { - write!(f, "{}: ", t)?; - } - - write!(f, "{}", self.msg)?; - - if let Some(ref s) = self.source { - write!(f, " source: {}", s)?; - } - - Ok(()) - } -} - -impl std::fmt::Debug for AnyError { - fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { - ::fmt(self, f)?; - - if let Some(ref b) = self.backtrace { - write!(f, "\nbacktrace:\n{}", b)?; - } - Ok(()) - } -} - -impl std::error::Error for AnyError { - fn source(&self) -> Option<&(dyn Error + 'static)> { - match &self.source { - Some(x) => Some(x.as_ref()), - None => None, - } - } -} - -impl From for AnyError { - fn from(a: anyhow::Error) -> Self { - AnyError::from_dyn(a.as_ref(), None) - } -} - -impl AnyError { - /// Convert some `Error` to AnyError. - /// - /// - If there is a `source()` in the input error, it is also converted to AnyError, recursively. - /// - A new backtrace will be built if there is not. - pub fn new(e: &E) -> Self - where E: Error + 'static { - let q: &(dyn Error + 'static) = e; - - let x = q.downcast_ref::(); - let typ = match x { - Some(ae) => ae.typ.clone(), - None => Some(std::any::type_name::().to_string()), - }; - - Self::from_dyn(e, typ) - } - - pub fn from_dyn(e: &(dyn Error + 'static), typ: Option) -> Self { - let x = e.downcast_ref::(); - - return match x { - Some(ae) => { - let mut res = ae.clone(); - if res.backtrace.is_none() { - res.backtrace = Some(format!("{:?}", Backtrace::new())); - } - res - } - None => { - let bt = match e.backtrace() { - Some(b) => Some(format!("{:?}", b)), - None => Some(format!("{:?}", Backtrace::new())), - }; - - let source = e.source().map(|x| Box::new(AnyError::from_dyn(x, None))); - - Self { - typ, - msg: e.to_string(), - source, - backtrace: bt, - } - } - }; - } - - pub fn get_type(&self) -> Option<&str> { - self.typ.as_ref().map(|x| x as _) - } - - pub fn backtrace(&self) -> Option<&str> { - self.backtrace.as_ref().map(|x| x as _) - } -} diff --git a/metasrv/src/any_error/mod.rs b/metasrv/src/any_error/mod.rs deleted file mode 100644 index 28c54f9d67811..0000000000000 --- a/metasrv/src/any_error/mod.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2021 Datafuse Labs. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -mod any_error_impl; - -pub use any_error_impl::AnyError; diff --git a/metasrv/src/errors.rs b/metasrv/src/errors.rs index 442c3e3756c30..f55e9289951d3 100644 --- a/metasrv/src/errors.rs +++ b/metasrv/src/errors.rs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +use anyerror::AnyError; use common_exception::ErrorCode; use common_exception::SerializedError; use common_meta_types::NodeId; @@ -19,8 +20,6 @@ use serde::Deserialize; use serde::Serialize; use thiserror::Error; -use crate::any_error::AnyError; - /// Top level error MetaNode would return. #[derive(Error, Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum MetaError { diff --git a/metasrv/src/lib.rs b/metasrv/src/lib.rs index 334280fcd97fe..cc6571ac484af 100644 --- a/metasrv/src/lib.rs +++ b/metasrv/src/lib.rs @@ -14,7 +14,6 @@ #![feature(backtrace)] -pub mod any_error; pub mod api; pub mod configs; pub mod errors; diff --git a/metasrv/tests/it/any_error.rs b/metasrv/tests/it/any_error.rs deleted file mode 100644 index 93cd52a60f5b2..0000000000000 --- a/metasrv/tests/it/any_error.rs +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2021 Datafuse Labs. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::error::Error; -use std::fmt; - -use anyhow::Context; -use databend_meta::any_error::AnyError; - -#[test] -fn test_any_error() -> anyhow::Result<()> { - // build from std Error - - let fmt_err = fmt::Error {}; - - let ae = AnyError::new(&fmt_err); - - let want_str = "core::fmt::Error: an error occurred when formatting an argument"; - assert_eq!(want_str, ae.to_string()); - assert!(ae.source().is_none()); - assert!(!ae.backtrace().unwrap().is_empty()); - - // debug output with backtrace - - let debug_str = format!("{:?}", ae); - - assert!(debug_str.starts_with(want_str)); - assert!(debug_str.contains("test_any_error")); - - // chained errors - - let err1 = anyhow::anyhow!("err1"); - let err2 = Err::<(), anyhow::Error>(err1).context("err2"); - - let ae = AnyError::from(err2.unwrap_err()); - - assert_eq!("err2 source: err1", ae.to_string()); - let src = ae.source().unwrap(); - assert_eq!("err1", src.to_string()); - assert!(!ae.backtrace().unwrap().is_empty()); - - // build AnyError from AnyError - - let ae2 = AnyError::new(&ae); - assert_eq!("err2 source: err1", ae.to_string()); - - let ser = serde_json::to_string(&ae2)?; - let de: AnyError = serde_json::from_str(&ser)?; - - assert_eq!("err2 source: err1", de.to_string()); - - Ok(()) -} diff --git a/metasrv/tests/it/main.rs b/metasrv/tests/it/main.rs index 7a864f1b2f944..70921a74ad962 100644 --- a/metasrv/tests/it/main.rs +++ b/metasrv/tests/it/main.rs @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -mod any_error; mod api; mod configs; mod grpc;