dbnexus/foundation/error/
mod.rs1#[derive(Debug, thiserror::Error)]
27pub enum DbError {
28 #[error(transparent)]
30 Connection(#[from] sea_orm::DbErr),
31
32 #[error("Configuration error: {0}")]
34 Config(String),
35
36 #[error("Permission denied: {0}")]
38 Permission(String),
39
40 #[error("Transaction error: {0}")]
42 Transaction(String),
43
44 #[error("Migration error: {0}")]
46 Migration(String),
47
48 #[cfg(feature = "validation")]
50 #[error("Validation error: {0}")]
51 Validation(String),
52}
53
54impl DbError {
55 pub fn new(error: sea_orm::DbErr) -> Self {
57 Self::Connection(error)
58 }
59
60 pub fn message(&self) -> String {
62 match self {
63 DbError::Connection(e) => e.to_string(),
64 DbError::Config(msg) => msg.clone(),
65 DbError::Permission(msg) => msg.clone(),
66 DbError::Transaction(msg) => msg.clone(),
67 DbError::Migration(msg) => msg.clone(),
68 #[cfg(feature = "validation")]
69 DbError::Validation(msg) => msg.clone(),
70 }
71 }
72}
73
74impl From<String> for DbError {
76 fn from(msg: String) -> Self {
77 Self::Config(msg)
78 }
79}
80
81impl From<&str> for DbError {
83 fn from(msg: &str) -> Self {
84 Self::Config(msg.to_string())
85 }
86}
87
88#[derive(Debug, thiserror::Error)]
90pub enum PoolError {
91 #[error("Failed to acquire connection within timeout")]
93 AcquireTimeout,
94
95 #[error("Connection pool exhausted")]
97 PoolExhausted,
98
99 #[error("Failed to create connection: {0}")]
101 ConnectionFailed(String),
102
103 #[error("Health check failed: {0}")]
105 HealthCheckFailed(String),
106}
107
108pub use crate::domain::permission::PermissionError;
118
119#[derive(Debug, thiserror::Error)]
121pub enum MigrationError {
122 #[error("Migration file not found: {0}")]
124 FileNotFound(String),
125
126 #[error("Failed to parse migration file: {0}")]
128 ParseError(String),
129
130 #[error("Migration execution failed: {0}")]
132 ExecutionError(String),
133
134 #[error("Migration version conflict: {0}")]
136 VersionConflict(String),
137
138 #[error("Migration rollback failed: {0}")]
140 RollbackError(String),
141}
142
143#[derive(Debug, thiserror::Error)]
145pub enum AuditError {
146 #[error("Failed to write audit log: {0}")]
148 WriteError(String),
149
150 #[error("Failed to serialize audit data: {0}")]
152 SerializationError(String),
153
154 #[error("Invalid audit configuration: {0}")]
156 ConfigError(String),
157}
158
159pub type DbResult<T> = Result<T, DbError>;
165pub type PermissionResult<T> = Result<T, PermissionError>;
167pub type PoolResult<T> = Result<T, PoolError>;
169pub type ConfigResult<T> = Result<T, crate::foundation::config::ConfigError>;
171pub type MigrationResult<T> = Result<T, MigrationError>;
173pub type AuditResult<T> = Result<T, AuditError>;
175
176#[cfg(test)]
181mod tests {
182 use super::*;
183
184 #[test]
186 fn test_db_error_creation() {
187 let db_err = sea_orm::DbErr::Custom("test error".to_string());
188 let error = DbError::new(db_err);
189 assert!(matches!(error, DbError::Connection(_)));
190 }
191
192 #[test]
194 fn test_db_error_from_string() {
195 let error: DbError = "custom error message".into();
196 assert!(matches!(error, DbError::Config(msg) if msg == "custom error message"));
197 }
198
199 #[test]
201 fn test_db_error_from_str() {
202 let error: DbError = "str error".into();
203 assert!(matches!(error, DbError::Config(msg) if msg == "str error"));
204 }
205
206 #[test]
208 fn test_db_error_variants() {
209 let config_err = DbError::Config("config issue".to_string());
210 assert!(matches!(config_err, DbError::Config(_)));
211
212 let perm_err = DbError::Permission("access denied".to_string());
213 assert!(matches!(perm_err, DbError::Permission(_)));
214
215 let tx_err = DbError::Transaction("tx failed".to_string());
216 assert!(matches!(tx_err, DbError::Transaction(_)));
217
218 let mig_err = DbError::Migration("migration failed".to_string());
219 assert!(matches!(mig_err, DbError::Migration(_)));
220 }
221
222 #[test]
224 fn test_pool_error_display() {
225 let error = PoolError::AcquireTimeout;
226 assert_eq!(error.to_string(), "Failed to acquire connection within timeout");
227
228 let error = PoolError::ConnectionFailed("network issue".to_string());
229 assert!(error.to_string().contains("network issue"));
230 }
231
232 #[test]
234 fn test_permission_error_display() {
235 let error = PermissionError::Denied {
236 resource: "users".to_string(),
237 operation: "delete".to_string(),
238 };
239 let msg = error.to_string();
240 assert!(msg.contains("users"));
241 assert!(msg.contains("delete"));
242
243 let error = PermissionError::RoleNotFound("admin".to_string());
244 assert!(error.to_string().contains("admin"));
245 }
246
247 #[test]
249 fn test_migration_error_display() {
250 let error = MigrationError::FileNotFound("v001.sql".to_string());
251 assert!(error.to_string().contains("v001.sql"));
252
253 let error = MigrationError::VersionConflict("v002".to_string());
254 assert!(error.to_string().contains("v002"));
255 }
256
257 #[test]
259 fn test_audit_error_display() {
260 let error = AuditError::WriteError("disk full".to_string());
261 assert!(error.to_string().contains("disk full"));
262
263 let error = AuditError::SerializationError("invalid JSON".to_string());
264 assert!(error.to_string().contains("invalid JSON"));
265 }
266}