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

* wip: global replace

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

* fix compile

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

* fix warnings

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

* remove unneeded tests of errors

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

* fix ErrorExt trait implementator

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

* fix warnings

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

* fix format

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

* fix pyo3 tests

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

---------

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

View File

@@ -16,7 +16,7 @@ use std::any::Any;
use common_error::ext::ErrorExt;
use common_error::prelude::{Snafu, StatusCode};
use snafu::{Backtrace, ErrorCompat};
use snafu::Location;
#[derive(Debug, Snafu)]
#[snafu(visibility(pub))]
@@ -34,7 +34,7 @@ pub enum Error {
},
#[snafu(display("Scripts table not found"))]
ScriptsTableNotFound { backtrace: Backtrace },
ScriptsTableNotFound { location: Location },
#[snafu(display(
"Failed to insert script to scripts table, name: {}, source: {}",
@@ -62,7 +62,7 @@ pub enum Error {
},
#[snafu(display("Script not found, name: {}", name))]
ScriptNotFound { backtrace: Backtrace, name: String },
ScriptNotFound { location: Location, name: String },
#[snafu(display("Failed to find script by name: {}", name))]
FindScript {
@@ -78,7 +78,7 @@ pub enum Error {
},
#[snafu(display("Failed to cast type, msg: {}", msg))]
CastType { msg: String, backtrace: Backtrace },
CastType { msg: String, location: Location },
}
pub type Result<T> = std::result::Result<T, Error>;
@@ -98,45 +98,7 @@ impl ErrorExt for Error {
}
}
fn backtrace_opt(&self) -> Option<&Backtrace> {
ErrorCompat::backtrace(self)
}
fn as_any(&self) -> &dyn Any {
self
}
}
#[cfg(test)]
mod tests {
use snafu::ResultExt;
use super::*;
fn throw_catalog_error() -> catalog::error::Result<()> {
catalog::error::IllegalManagerStateSnafu { msg: "test" }.fail()
}
fn throw_python_error() -> crate::python::error::Result<()> {
crate::python::error::CoprParseSnafu {
reason: "test",
loc: None,
}
.fail()
}
#[test]
fn test_error() {
let err = throw_catalog_error()
.context(FindScriptsTableSnafu)
.unwrap_err();
assert_eq!(StatusCode::Unexpected, err.status_code());
assert!(err.backtrace_opt().is_some());
let err = throw_python_error()
.context(ExecutePythonSnafu { name: "test" })
.unwrap_err();
assert_eq!(StatusCode::InvalidArguments, err.status_code());
assert!(err.backtrace_opt().is_some());
}
}

View File

@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use common_error::prelude::{ErrorCompat, ErrorExt, StatusCode};
use common_error::prelude::{ErrorExt, StatusCode};
use console::{style, Style};
use datafusion::error::DataFusionError;
use datatypes::arrow::error::ArrowError;
@@ -23,7 +23,7 @@ use rustpython_parser::ast::Location;
use rustpython_parser::error::ParseError;
pub use snafu::ensure;
use snafu::prelude::Snafu;
use snafu::Backtrace;
use snafu::Location as SnafuLocation;
pub type Result<T> = std::result::Result<T, Error>;
pub(crate) fn ret_other_error_with(reason: String) -> OtherSnafu<String> {
@@ -47,29 +47,32 @@ pub enum Error {
#[snafu(display("Failed to parse script, source: {}", source))]
PyParse {
backtrace: Backtrace,
location: SnafuLocation,
source: ParseError,
},
#[snafu(display("Failed to compile script, source: {}", source))]
PyCompile {
backtrace: Backtrace,
location: SnafuLocation,
source: CodegenError,
},
/// rustpython problem, using python virtual machines' backtrace instead
#[snafu(display("Python Runtime error, error: {}", msg))]
PyRuntime { msg: String, backtrace: Backtrace },
PyRuntime {
msg: String,
location: SnafuLocation,
},
#[snafu(display("Arrow error: {}", source))]
Arrow {
backtrace: Backtrace,
location: SnafuLocation,
source: ArrowError,
},
#[snafu(display("DataFusion error: {}", source))]
DataFusion {
backtrace: Backtrace,
location: SnafuLocation,
source: DataFusionError,
},
@@ -81,7 +84,7 @@ pub enum Error {
"".into()
}))]
CoprParse {
backtrace: Backtrace,
location: SnafuLocation,
reason: String,
// location is option because maybe errors can't give a clear location?
loc: Option<Location>,
@@ -90,15 +93,18 @@ pub enum Error {
/// Other types of error that isn't any of above
#[snafu(display("Coprocessor's Internal error: {}", reason))]
Other {
backtrace: Backtrace,
location: SnafuLocation,
reason: String,
},
#[snafu(display("Unsupported sql in coprocessor: {}", sql))]
UnsupportedSql { sql: String, backtrace: Backtrace },
UnsupportedSql {
sql: String,
location: SnafuLocation,
},
#[snafu(display("Missing sql in coprocessor"))]
MissingSql { backtrace: Backtrace },
MissingSql { location: SnafuLocation },
#[snafu(display("Failed to retrieve record batches, source: {}", source))]
RecordBatch {
@@ -140,9 +146,6 @@ impl ErrorExt for Error {
| Error::MissingSql { .. } => StatusCode::InvalidArguments,
}
}
fn backtrace_opt(&self) -> Option<&common_error::snafu::Backtrace> {
ErrorCompat::backtrace(self)
}
fn as_any(&self) -> &dyn std::any::Any {
self
@@ -224,24 +227,3 @@ pub fn get_error_reason_loc(err: &Error) -> (String, Option<Location>) {
_ => (format!("Unknown error: {err:?}"), None),
}
}
#[cfg(test)]
mod tests {
use snafu::ResultExt;
use super::*;
fn throw_query_error() -> query::error::Result<()> {
query::error::TableNotFoundSnafu {
table: String::new(),
}
.fail()
}
#[test]
fn test_error() {
let err = throw_query_error().context(DatabaseQuerySnafu).unwrap_err();
assert_eq!(StatusCode::InvalidArguments, err.status_code());
assert!(err.backtrace_opt().is_some());
}
}

View File

@@ -22,7 +22,7 @@ use datatypes::vectors::{Helper, VectorRef};
use pyo3::exceptions::{PyRuntimeError, PyValueError};
use pyo3::types::{PyBool, PyDict, PyFloat, PyInt, PyList, PyModule, PyString, PyTuple};
use pyo3::{pymethods, PyAny, PyCell, PyObject, PyResult, Python, ToPyObject};
use snafu::{ensure, Backtrace, GenerateImplicitData, ResultExt};
use snafu::{ensure, Location, ResultExt};
use crate::python::error::{self, NewRecordBatchSnafu, OtherSnafu, Result};
use crate::python::ffi_types::copr::PyQueryEngine;
@@ -149,7 +149,7 @@ coprocessor = copr
})()
.map_err(|err| error::Error::PyRuntime {
msg: err.into_value(py).to_string(),
backtrace: Backtrace::generate(),
location: snafu::location!(),
})?;
ensure!(
cols.len() == copr.deco_args.ret_names.len(),

View File

@@ -255,7 +255,7 @@ def calc_rvs(open_time, close):
.unwrap();
let ret = exec_coprocessor(python_source, &Some(rb));
if let Err(Error::PyParse {
backtrace: _,
location: _,
source,
}) = ret
{
@@ -305,7 +305,7 @@ def a(cpu, mem):
.unwrap();
let ret = exec_coprocessor(python_source, &Some(rb));
if let Err(Error::PyParse {
backtrace: _,
location: _,
source,
}) = ret
{

View File

@@ -23,7 +23,7 @@ use datatypes::vectors::{
};
use rustpython_vm::builtins::{PyBaseExceptionRef, PyBool, PyFloat, PyInt, PyList, PyStr};
use rustpython_vm::{PyObjectRef, PyPayload, PyResult, VirtualMachine};
use snafu::{Backtrace, GenerateImplicitData, OptionExt, ResultExt};
use snafu::{OptionExt, ResultExt};
use crate::python::error;
use crate::python::error::ret_other_error_with;
@@ -39,16 +39,13 @@ pub fn is_instance<T: PyPayload>(obj: &PyObjectRef, vm: &VirtualMachine) -> bool
pub fn format_py_error(excep: PyBaseExceptionRef, vm: &VirtualMachine) -> error::Error {
let mut msg = String::new();
if let Err(e) = vm.write_exception(&mut msg, &excep) {
return error::Error::PyRuntime {
return error::PyRuntimeSnafu {
msg: format!("Failed to write exception msg, err: {e}"),
backtrace: Backtrace::generate(),
};
}
.build();
}
error::Error::PyRuntime {
msg,
backtrace: Backtrace::generate(),
}
error::PyRuntimeSnafu { msg }.build()
}
pub(crate) fn py_obj_to_value(obj: &PyObjectRef, vm: &VirtualMachine) -> PyResult<Value> {

View File

@@ -16,7 +16,6 @@ use futures::Future;
use once_cell::sync::OnceCell;
use rustpython_vm::builtins::PyBaseExceptionRef;
use rustpython_vm::{PyObjectRef, PyPayload, VirtualMachine};
use snafu::{Backtrace, GenerateImplicitData};
use tokio::runtime::Runtime;
use crate::python::error;
@@ -30,16 +29,12 @@ pub fn is_instance<T: PyPayload>(obj: &PyObjectRef, vm: &VirtualMachine) -> bool
pub fn format_py_error(excep: PyBaseExceptionRef, vm: &VirtualMachine) -> error::Error {
let mut msg = String::new();
if let Err(e) = vm.write_exception(&mut msg, &excep) {
return error::Error::PyRuntime {
return error::PyRuntimeSnafu {
msg: format!("Failed to write exception msg, err: {e}"),
backtrace: Backtrace::generate(),
};
}
error::Error::PyRuntime {
msg,
backtrace: Backtrace::generate(),
}
.build();
}
error::PyRuntimeSnafu { msg }.build()
}
static LOCAL_RUNTIME: OnceCell<tokio::runtime::Runtime> = OnceCell::new();
fn get_local_runtime() -> std::thread::Result<&'static Runtime> {