Skip to main content

noxu_persist/
error.rs

1//! Error types for the persistence layer.
2//!
3//! # v1.5.1 cleanup (Wave 1C, persist-xa Low audit)
4//!
5//! Four `PersistError` variants used to live here that no production
6//! call site ever returned: `EntityNotFound`, `DuplicateKey`,
7//! `InvalidEntity`, `StoreAlreadyOpen`.  They were removed because
8//! the public surface advertises an error variant the engine cannot
9//! actually emit.  Migration:
10//!
11//! * `EntityNotFound` — `PrimaryIndex::get` returns `Result<Option<E>>`
12//!   already; absence is `Ok(None)`, never an error.
13//! * `DuplicateKey` — `PrimaryIndex::put` is overwrite-by-default; if
14//!   the user wants "insert or fail", they should use the
15//!   `Database::put_no_overwrite` shape and check the
16//!   `OperationStatus::KeyExist` status bit instead.
17//! * `InvalidEntity` — entity validation is the application's
18//!   responsibility; raise an application-level error type or
19//!   `PersistError::SerializationError` instead.
20//! * `StoreAlreadyOpen` — `EntityStore::open` cannot fail with this:
21//!   each call constructs a fresh handle.
22
23use thiserror::Error;
24
25/// Errors that can occur in the persistence layer.
26///
27#[derive(Debug, Error)]
28pub enum PersistError {
29    /// An error from the underlying database layer.
30    #[error("database error: {0}")]
31    DatabaseError(#[from] noxu_db::NoxuError),
32
33    /// An error occurred during serialization or deserialization.
34    #[error("serialization error: {0}")]
35    SerializationError(String),
36
37    /// The entity store is not open.
38    #[error("store not open")]
39    StoreNotOpen,
40
41    /// The requested index is not available.
42    #[error("index not available: {0}")]
43    IndexNotAvailable(String),
44}
45
46/// Result type for persistence layer operations.
47pub type Result<T> = std::result::Result<T, PersistError>;
48
49#[cfg(test)]
50mod tests {
51    use super::*;
52
53    #[test]
54    fn test_serialization_error_display() {
55        let err = PersistError::SerializationError("bad format".to_string());
56        assert_eq!(err.to_string(), "serialization error: bad format");
57    }
58
59    #[test]
60    fn test_store_not_open_display() {
61        let err = PersistError::StoreNotOpen;
62        assert_eq!(err.to_string(), "store not open");
63    }
64
65    #[test]
66    fn test_index_not_available_display() {
67        let err = PersistError::IndexNotAvailable("email_idx".to_string());
68        assert_eq!(err.to_string(), "index not available: email_idx");
69    }
70
71    #[test]
72    fn test_database_error_from() {
73        let db_err = noxu_db::NoxuError::DatabaseClosed;
74        let err: PersistError = db_err.into();
75        assert!(matches!(err, PersistError::DatabaseError(_)));
76        assert!(err.to_string().contains("database error"));
77    }
78}