Skip to main content

sentinel_dbms/
error.rs

1use thiserror::Error;
2
3/// Sentinel-wide error type for the document DBMS.
4///
5/// This error type encompasses all possible errors that can occur within
6/// the Sentinel system, providing structured error handling and meaningful
7/// error messages for different failure scenarios.
8#[derive(Error, Debug)]
9pub enum SentinelError {
10    /// I/O operations failed (file system, network, etc.)
11    #[error("I/O error: {source}")]
12    Io {
13        #[from]
14        source: std::io::Error,
15    },
16
17    /// JSON serialization/deserialization failed
18    #[error("JSON error: {source}")]
19    Json {
20        #[from]
21        source: serde_json::Error,
22    },
23
24    /// Document not found in collection
25    #[error("Document '{id}' not found in collection '{collection}'")]
26    DocumentNotFound {
27        id:         String,
28        collection: String,
29    },
30
31    /// Collection not found in store
32    #[error("Collection '{name}' not found in store")]
33    CollectionNotFound {
34        name: String,
35    },
36
37    /// Document already exists (for operations that require uniqueness)
38    #[error("Document '{id}' already exists in collection '{collection}'")]
39    DocumentAlreadyExists {
40        id:         String,
41        collection: String,
42    },
43
44    /// Invalid document ID format
45    #[error("Invalid document ID: {id}")]
46    InvalidDocumentId {
47        id: String,
48    },
49
50    /// Invalid collection name format
51    #[error("Invalid collection name: {name}")]
52    InvalidCollectionName {
53        name: String,
54    },
55
56    /// Store is corrupted or in an invalid state
57    #[error("Store corruption detected: {reason}")]
58    StoreCorruption {
59        reason: String,
60    },
61
62    /// Transaction failed
63    #[error("Transaction failed: {reason}")]
64    TransactionFailed {
65        reason: String,
66    },
67
68    /// Lock acquisition failed
69    #[error("Lock acquisition failed: {reason}")]
70    LockFailed {
71        reason: String,
72    },
73
74    /// Encryption/decryption operation failed
75    #[error("Cryptographic operation failed: {operation}")]
76    CryptoFailed {
77        operation: String,
78    },
79
80    /// WAL (Write-Ahead Logging) operations failed
81    #[error("WAL error: {source}")]
82    Wal {
83        #[from]
84        source: sentinel_wal::WalError,
85    },
86
87    /// Configuration error
88    #[error("Configuration error: {message}")]
89    ConfigError {
90        message: String,
91    },
92
93    /// Document hash verification failed
94    #[error("Document '{id}' hash verification failed: {reason}")]
95    HashVerificationFailed {
96        id:     String,
97        reason: String,
98    },
99
100    /// Document signature verification failed
101    #[error("Document '{id}' signature verification failed: {reason}")]
102    SignatureVerificationFailed {
103        id:     String,
104        reason: String,
105    },
106
107    /// Generic error for unexpected conditions
108    #[error("Internal error: {message}")]
109    Internal {
110        message: String,
111    },
112}
113
114/// Result type alias for Sentinel operations.
115pub type Result<T> = std::result::Result<T, SentinelError>;
116
117impl From<sentinel_crypto::CryptoError> for SentinelError {
118    fn from(err: sentinel_crypto::CryptoError) -> Self {
119        Self::CryptoFailed {
120            operation: err.to_string(),
121        }
122    }
123}
124
125#[cfg(test)]
126mod tests {
127    use super::*;
128
129    #[test]
130    fn test_sentinel_error_from_crypto_error() {
131        let crypto_err = sentinel_crypto::CryptoError::Encryption;
132        let sentinel_err: SentinelError = crypto_err.into();
133        match sentinel_err {
134            SentinelError::CryptoFailed {
135                operation,
136            } => {
137                assert!(!operation.is_empty());
138            },
139            _ => panic!("Expected CryptoFailed"),
140        }
141    }
142}