1use thiserror::Error;
2
3#[derive(Error, Debug)]
9pub enum SentinelError {
10 #[error("I/O error: {source}")]
12 Io {
13 #[from]
14 source: std::io::Error,
15 },
16
17 #[error("JSON error: {source}")]
19 Json {
20 #[from]
21 source: serde_json::Error,
22 },
23
24 #[error("Document '{id}' not found in collection '{collection}'")]
26 DocumentNotFound {
27 id: String,
28 collection: String,
29 },
30
31 #[error("Collection '{name}' not found in store")]
33 CollectionNotFound {
34 name: String,
35 },
36
37 #[error("Document '{id}' already exists in collection '{collection}'")]
39 DocumentAlreadyExists {
40 id: String,
41 collection: String,
42 },
43
44 #[error("Invalid document ID: {id}")]
46 InvalidDocumentId {
47 id: String,
48 },
49
50 #[error("Invalid collection name: {name}")]
52 InvalidCollectionName {
53 name: String,
54 },
55
56 #[error("Store corruption detected: {reason}")]
58 StoreCorruption {
59 reason: String,
60 },
61
62 #[error("Transaction failed: {reason}")]
64 TransactionFailed {
65 reason: String,
66 },
67
68 #[error("Lock acquisition failed: {reason}")]
70 LockFailed {
71 reason: String,
72 },
73
74 #[error("Cryptographic operation failed: {operation}")]
76 CryptoFailed {
77 operation: String,
78 },
79
80 #[error("WAL error: {source}")]
82 Wal {
83 #[from]
84 source: sentinel_wal::WalError,
85 },
86
87 #[error("Configuration error: {message}")]
89 ConfigError {
90 message: String,
91 },
92
93 #[error("Document '{id}' hash verification failed: {reason}")]
95 HashVerificationFailed {
96 id: String,
97 reason: String,
98 },
99
100 #[error("Document '{id}' signature verification failed: {reason}")]
102 SignatureVerificationFailed {
103 id: String,
104 reason: String,
105 },
106
107 #[error("Internal error: {message}")]
109 Internal {
110 message: String,
111 },
112}
113
114pub 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}