mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-05-21 15:30:40 +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:
@@ -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> {
|
||||
|
||||
Reference in New Issue
Block a user