114 lines
3.4 KiB
Rust
114 lines
3.4 KiB
Rust
use pyo3::create_exception;
|
|
use pyo3::exceptions::PyException;
|
|
use pyo3::exceptions::PyNotImplementedError;
|
|
use pyo3::prelude::*;
|
|
use pyo3::types::PyModule;
|
|
use qroissant_transport::TransportError;
|
|
use thiserror::Error;
|
|
|
|
create_exception!(
|
|
qroissant,
|
|
QroissantError,
|
|
PyException,
|
|
"Base exception for qroissant errors."
|
|
);
|
|
create_exception!(
|
|
qroissant,
|
|
DecodeError,
|
|
QroissantError,
|
|
"Raised when q IPC payload decoding fails."
|
|
);
|
|
create_exception!(
|
|
qroissant,
|
|
ProtocolError,
|
|
QroissantError,
|
|
"Raised when q IPC framing or protocol validation fails."
|
|
);
|
|
create_exception!(
|
|
qroissant,
|
|
TransportErrorPy,
|
|
QroissantError,
|
|
"Raised when transport IO or socket operations fail."
|
|
);
|
|
create_exception!(
|
|
qroissant,
|
|
OperationError,
|
|
QroissantError,
|
|
"Raised when an operation is unsupported in the current state."
|
|
);
|
|
create_exception!(
|
|
qroissant,
|
|
QRuntimeError,
|
|
QroissantError,
|
|
"Raised when the remote q process returns an error response."
|
|
);
|
|
create_exception!(
|
|
qroissant,
|
|
PoolError,
|
|
QroissantError,
|
|
"Raised when connection pool management fails."
|
|
);
|
|
create_exception!(
|
|
qroissant,
|
|
PoolClosedError,
|
|
PoolError,
|
|
"Raised when a closed pool is used."
|
|
);
|
|
|
|
#[derive(Debug, Error)]
|
|
pub enum PythonError {
|
|
#[error("{0}")]
|
|
Decode(String),
|
|
#[error("{0}")]
|
|
Protocol(String),
|
|
#[error("{0}")]
|
|
Transport(String),
|
|
#[error("{0}")]
|
|
Operation(String),
|
|
#[error("{0}")]
|
|
QRuntime(String),
|
|
#[error("{0}")]
|
|
Pool(String),
|
|
#[error("connection pool is closed")]
|
|
PoolClosed,
|
|
#[error("{0}")]
|
|
NotImplemented(String),
|
|
}
|
|
|
|
pub type PythonResult<T> = Result<T, PythonError>;
|
|
|
|
pub fn register(module: &Bound<'_, PyModule>) -> PyResult<()> {
|
|
let py = module.py();
|
|
module.add("QroissantError", py.get_type::<QroissantError>())?;
|
|
module.add("DecodeError", py.get_type::<DecodeError>())?;
|
|
module.add("ProtocolError", py.get_type::<ProtocolError>())?;
|
|
module.add("TransportError", py.get_type::<TransportErrorPy>())?;
|
|
module.add("OperationError", py.get_type::<OperationError>())?;
|
|
module.add("QRuntimeError", py.get_type::<QRuntimeError>())?;
|
|
module.add("PoolError", py.get_type::<PoolError>())?;
|
|
module.add("PoolClosedError", py.get_type::<PoolClosedError>())?;
|
|
Ok(())
|
|
}
|
|
|
|
pub fn to_py_err(error: PythonError) -> PyErr {
|
|
match error {
|
|
PythonError::Decode(message) => DecodeError::new_err(message),
|
|
PythonError::Protocol(message) => ProtocolError::new_err(message),
|
|
PythonError::Transport(message) => TransportErrorPy::new_err(message),
|
|
PythonError::Operation(message) => OperationError::new_err(message),
|
|
PythonError::QRuntime(message) => QRuntimeError::new_err(message),
|
|
PythonError::Pool(message) => PoolError::new_err(message),
|
|
PythonError::PoolClosed => PoolClosedError::new_err("connection pool is closed"),
|
|
PythonError::NotImplemented(message) => PyNotImplementedError::new_err(message),
|
|
}
|
|
}
|
|
|
|
pub fn map_transport_error(error: TransportError) -> PythonError {
|
|
match error {
|
|
TransportError::Closed => PythonError::Operation(error.to_string()),
|
|
TransportError::Protocol(_) => PythonError::Protocol(error.to_string()),
|
|
TransportError::Io(_)
|
|
| TransportError::InvalidEndpoint(_)
|
|
| TransportError::InvalidQueryLength(_) => PythonError::Transport(error.to_string()),
|
|
}
|
|
}
|