libsoliton/soliton_py/src/errors.rs
Kamal Tufekcic 1d99048c95
Some checks failed
CI / lint (push) Successful in 1m37s
CI / test-python (push) Successful in 1m49s
CI / test-zig (push) Successful in 1m39s
CI / test-wasm (push) Successful in 1m54s
CI / test (push) Successful in 14m44s
CI / miri (push) Successful in 14m18s
CI / build (push) Successful in 1m9s
CI / fuzz-regression (push) Successful in 9m9s
CI / publish (push) Failing after 1m10s
CI / publish-python (push) Failing after 1m46s
CI / publish-wasm (push) Has been cancelled
initial commit
Signed-off-by: Kamal Tufekcic <kamal@lo.sh>
2026-04-02 23:48:10 +03:00

131 lines
3.8 KiB
Rust

//! Error type mapping from soliton::error::Error to Python exceptions.
use pyo3::create_exception;
use pyo3::exceptions::PyException;
use pyo3::prelude::*;
// Each soliton error variant gets a dedicated Python exception class,
// all inheriting from SolitonError.
create_exception!(
soliton,
SolitonError,
PyException,
"Base exception for all soliton errors."
);
create_exception!(
soliton,
InvalidLengthError,
SolitonError,
"Wrong-size parameter."
);
create_exception!(
soliton,
InvalidDataError,
SolitonError,
"Structurally invalid content."
);
create_exception!(soliton, AeadError, SolitonError, "AEAD decryption failed.");
create_exception!(
soliton,
VerificationError,
SolitonError,
"Signature verification failed."
);
create_exception!(
soliton,
BundleVerificationError,
SolitonError,
"Pre-key bundle verification failed."
);
create_exception!(
soliton,
DecapsulationError,
SolitonError,
"KEM decapsulation failed."
);
create_exception!(
soliton,
DuplicateMessageError,
SolitonError,
"Replayed or already-seen message."
);
create_exception!(
soliton,
ChainExhaustedError,
SolitonError,
"Counter-space exhausted."
);
create_exception!(
soliton,
UnsupportedVersionError,
SolitonError,
"Unsupported blob version."
);
create_exception!(
soliton,
UnsupportedCryptoVersionError,
SolitonError,
"Unrecognized crypto version."
);
create_exception!(
soliton,
InternalError,
SolitonError,
"Internal invariant violated."
);
/// Convert a soliton::error::Error into the appropriate Python exception.
pub fn to_py_err(e: soliton::error::Error) -> PyErr {
use soliton::error::Error;
match e {
Error::InvalidLength { .. } => InvalidLengthError::new_err(e.to_string()),
Error::InvalidData => InvalidDataError::new_err(e.to_string()),
Error::AeadFailed => AeadError::new_err(e.to_string()),
Error::VerificationFailed => VerificationError::new_err(e.to_string()),
Error::BundleVerificationFailed => BundleVerificationError::new_err(e.to_string()),
Error::DecapsulationFailed => DecapsulationError::new_err(e.to_string()),
Error::DuplicateMessage => DuplicateMessageError::new_err(e.to_string()),
Error::ChainExhausted => ChainExhaustedError::new_err(e.to_string()),
Error::UnsupportedVersion => UnsupportedVersionError::new_err(e.to_string()),
Error::UnsupportedCryptoVersion => UnsupportedCryptoVersionError::new_err(e.to_string()),
Error::Internal => InternalError::new_err(e.to_string()),
_ => SolitonError::new_err(e.to_string()),
}
}
pub fn register(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add("SolitonError", m.py().get_type::<SolitonError>())?;
m.add(
"InvalidLengthError",
m.py().get_type::<InvalidLengthError>(),
)?;
m.add("InvalidDataError", m.py().get_type::<InvalidDataError>())?;
m.add("AeadError", m.py().get_type::<AeadError>())?;
m.add("VerificationError", m.py().get_type::<VerificationError>())?;
m.add(
"BundleVerificationError",
m.py().get_type::<BundleVerificationError>(),
)?;
m.add(
"DecapsulationError",
m.py().get_type::<DecapsulationError>(),
)?;
m.add(
"DuplicateMessageError",
m.py().get_type::<DuplicateMessageError>(),
)?;
m.add(
"ChainExhaustedError",
m.py().get_type::<ChainExhaustedError>(),
)?;
m.add(
"UnsupportedVersionError",
m.py().get_type::<UnsupportedVersionError>(),
)?;
m.add(
"UnsupportedCryptoVersionError",
m.py().get_type::<UnsupportedCryptoVersionError>(),
)?;
m.add("InternalError", m.py().get_type::<InternalError>())?;
Ok(())
}