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

View file

@ -1528,6 +1528,15 @@ impl Backend {
pub fn db_command(&self, input: &[u8]) -> Result<Vec<u8>> { pub fn db_command(&self, input: &[u8]) -> Result<Vec<u8>> {
self.with_col(|col| db_command_bytes(&col.storage, input)) 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> { fn to_nids(ids: Vec<i64>) -> Vec<NoteID> {

View file

@ -16,7 +16,6 @@ struct Backend {
backend: RustBackend, backend: RustBackend,
} }
create_exception!(ankirspy, DBError, Exception);
create_exception!(ankirspy, BackendError, Exception); create_exception!(ankirspy, BackendError, Exception);
#[pyfunction] #[pyfunction]
@ -140,12 +139,14 @@ impl Backend {
.map_err(|err_bytes| BackendError::py_err(err_bytes)) .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> { fn db_command(&mut self, py: Python, input: &PyBytes) -> PyResult<PyObject> {
let in_bytes = input.as_bytes(); let in_bytes = input.as_bytes();
let out_res = py.allow_threads(move || { let out_res = py.allow_threads(move || {
self.backend self.backend
.db_command(in_bytes) .run_db_command_bytes(in_bytes)
.map_err(|e| DBError::py_err(e.localized_description(&self.backend.i18n()))) .map_err(|err_bytes| BackendError::py_err(err_bytes))
}); });
let out_bytes = out_res?; let out_bytes = out_res?;
let out_obj = PyBytes::new(py, &out_bytes); let out_obj = PyBytes::new(py, &out_bytes);