Skip to main content

citadel_core/
error.rs

1use crate::types::PageId;
2
3pub type Result<T> = std::result::Result<T, Error>;
4
5#[derive(Debug, thiserror::Error)]
6pub enum Error {
7    #[error("page {0} failed MAC verification: data has been tampered with")]
8    PageTampered(PageId),
9
10    #[error("incorrect passphrase or wrong key file")]
11    BadPassphrase,
12
13    #[error("database file is locked by another process")]
14    DatabaseLocked,
15
16    #[error("key file does not match data file (file_id mismatch)")]
17    KeyFileMismatch,
18
19    #[error("transaction requires more pages than buffer pool capacity ({capacity})")]
20    TransactionTooLarge { capacity: usize },
21
22    #[error("database file is corrupted: both commit slots are invalid")]
23    DatabaseCorrupted,
24
25    #[error("page checksum mismatch on page {0} (post-decrypt integrity failure)")]
26    ChecksumMismatch(PageId),
27
28    #[error("invalid page type {0} on page {1}")]
29    InvalidPageType(u16, PageId),
30
31    #[error("key too large: {size} bytes (max {max})")]
32    KeyTooLarge { size: usize, max: usize },
33
34    #[error("value too large: {size} bytes (max {max})")]
35    ValueTooLarge { size: usize, max: usize },
36
37    #[error("invalid magic number: expected 0x{expected:08X}, found 0x{found:08X}")]
38    InvalidMagic { expected: u32, found: u32 },
39
40    #[error("unsupported format version: {0}")]
41    UnsupportedVersion(u32),
42
43    #[error("key file integrity check failed (HMAC mismatch)")]
44    KeyFileIntegrity,
45
46    #[error("invalid key file magic")]
47    InvalidKeyFileMagic,
48
49    #[error("key unwrap failed (AES-KW integrity check)")]
50    KeyUnwrapFailed,
51
52    #[error("no write transaction active")]
53    NoWriteTransaction,
54
55    #[error("a write transaction is already active")]
56    WriteTransactionActive,
57
58    #[error("page {0} is out of bounds (beyond high water mark)")]
59    PageOutOfBounds(PageId),
60
61    #[error("buffer pool is full and all pages are pinned")]
62    BufferPoolFull,
63
64    #[error("unsupported cipher: {0}")]
65    UnsupportedCipher(u8),
66
67    #[error("unsupported KDF algorithm: {0}")]
68    UnsupportedKdf(u8),
69
70    #[error("FIPS mode violation: {0}")]
71    FipsViolation(String),
72
73    #[error("table not found: {0}")]
74    TableNotFound(String),
75
76    #[error("table already exists: {0}")]
77    TableAlreadyExists(String),
78
79    #[error("passphrase is required")]
80    PassphraseRequired,
81
82    #[error("sync error: {0}")]
83    Sync(String),
84
85    #[error("I/O error: {0}")]
86    Io(#[from] std::io::Error),
87}
88
89#[cfg(test)]
90mod tests {
91    use super::*;
92
93    #[test]
94    fn error_display() {
95        let e = Error::PageTampered(PageId(42));
96        assert!(format!("{e}").contains("page:42"));
97
98        let e = Error::TransactionTooLarge { capacity: 256 };
99        assert!(format!("{e}").contains("256"));
100    }
101
102    #[test]
103    fn error_from_io() {
104        let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
105        let e: Error = io_err.into();
106        assert!(matches!(e, Error::Io(_)));
107    }
108}