handle db errors the same way as other backend requests

This commit is contained in:
Damien Elmes 2020-06-12 20:39:02 +10:00
parent cf6d4f1cb9
commit 8e895aa247
3 changed files with 21 additions and 5 deletions

View file

@ -233,7 +233,13 @@ class RustBackend(RustBackendGenerated):
return self._db_command(dict(kind="rollback"))
def _db_command(self, input: Dict[str, Any]) -> Any:
return from_json_bytes(self._backend.db_command(to_json_bytes(input)))
try:
return from_json_bytes(self._backend.db_command(to_json_bytes(input)))
except Exception as e:
err_bytes = bytes(e.args[0])
err = pb.BackendError()
err.ParseFromString(err_bytes)
raise proto_exception_to_native(err)
def translate(self, key: TRValue, **kwargs: Union[str, int, float]) -> str:
return self.translate_string(translate_string_in(key, **kwargs))
@ -254,7 +260,7 @@ class RustBackend(RustBackendGenerated):
return self._backend.command(method, input_bytes)
except Exception as e:
err_bytes = bytes(e.args[0])
err = pb.BackendError()
err = pb.BackendError()
err.ParseFromString(err_bytes)
raise proto_exception_to_native(err)

View file

@ -1528,6 +1528,15 @@ impl Backend {
pub fn db_command(&self, input: &[u8]) -> Result<Vec<u8>> {
self.with_col(|col| db_command_bytes(&col.storage, input))
}
pub fn run_db_command_bytes(&self, input: &[u8]) -> std::result::Result<Vec<u8>, Vec<u8>> {
self.db_command(input).map_err(|err| {
let backend_err = anki_error_to_proto_error(err, &self.i18n);
let mut bytes = Vec::new();
backend_err.encode(&mut bytes).unwrap();
bytes
})
}
}
fn to_nids(ids: Vec<i64>) -> Vec<NoteID> {

View file

@ -16,7 +16,6 @@ struct Backend {
backend: RustBackend,
}
create_exception!(ankirspy, DBError, Exception);
create_exception!(ankirspy, BackendError, Exception);
#[pyfunction]
@ -140,12 +139,14 @@ impl Backend {
.map_err(|err_bytes| BackendError::py_err(err_bytes))
}
/// This takes and returns JSON, due to Python's slow protobuf
/// encoding/decoding.
fn db_command(&mut self, py: Python, input: &PyBytes) -> PyResult<PyObject> {
let in_bytes = input.as_bytes();
let out_res = py.allow_threads(move || {
self.backend
.db_command(in_bytes)
.map_err(|e| DBError::py_err(e.localized_description(&self.backend.i18n())))
.run_db_command_bytes(in_bytes)
.map_err(|err_bytes| BackendError::py_err(err_bytes))
});
let out_bytes = out_res?;
let out_obj = PyBytes::new(py, &out_bytes);