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}