Skip to main content

reinhardt_db/backends/
error.rs

1//! Error types for database operations
2
3use thiserror::Error;
4
5/// Database operation errors
6#[non_exhaustive]
7#[derive(Error, Debug, Clone, PartialEq, Eq)]
8pub enum DatabaseError {
9	/// Feature not supported by this database
10	#[error("Feature '{feature}' is not supported by {database}")]
11	UnsupportedFeature {
12		/// The database that does not support the feature.
13		database: String,
14		/// The feature that is not supported.
15		feature: String,
16	},
17
18	/// Operation not supported by this backend
19	#[error("Not supported: {0}")]
20	NotSupported(String),
21
22	/// SQL syntax error
23	#[error("SQL syntax error: {0}")]
24	SyntaxError(String),
25
26	/// Type conversion error
27	#[error("Type conversion error: {0}")]
28	TypeError(String),
29
30	/// Connection error
31	#[error("Connection error: {0}")]
32	ConnectionError(String),
33
34	/// Query execution error
35	#[error("Query execution error: {0}")]
36	QueryError(String),
37
38	/// Serialization/deserialization error
39	#[error("Serialization error: {0}")]
40	SerializationError(String),
41
42	/// Configuration error
43	#[error("Configuration error: {0}")]
44	ConfigError(String),
45
46	/// Column not found error
47	#[error("Column not found: {0}")]
48	ColumnNotFound(String),
49
50	/// Transaction error
51	#[error("Transaction error: {0}")]
52	TransactionError(String),
53
54	/// Generic database error
55	#[error("Database error: {0}")]
56	Other(String),
57}
58
59/// Result type for database operations
60pub type Result<T> = std::result::Result<T, DatabaseError>;
61
62impl From<serde_json::Error> for DatabaseError {
63	fn from(err: serde_json::Error) -> Self {
64		DatabaseError::SerializationError(err.to_string())
65	}
66}
67
68impl From<sqlx::Error> for DatabaseError {
69	fn from(err: sqlx::Error) -> Self {
70		use sqlx::Error::*;
71		match err {
72			Configuration(msg) => DatabaseError::ConfigError(msg.to_string()),
73			Database(e) => DatabaseError::QueryError(e.to_string()),
74			Io(e) => DatabaseError::ConnectionError(e.to_string()),
75			Tls(e) => DatabaseError::ConnectionError(e.to_string()),
76			Protocol(msg) => DatabaseError::QueryError(msg),
77			RowNotFound => DatabaseError::QueryError("Row not found".to_string()),
78			TypeNotFound { type_name } => {
79				DatabaseError::TypeError(format!("Type not found: {}", type_name))
80			}
81			ColumnIndexOutOfBounds { index, len } => DatabaseError::QueryError(format!(
82				"Column index {} out of bounds (len: {})",
83				index, len
84			)),
85			ColumnNotFound(name) => {
86				DatabaseError::QueryError(format!("Column not found: {}", name))
87			}
88			ColumnDecode { index, source } => {
89				DatabaseError::TypeError(format!("Failed to decode column {}: {}", index, source))
90			}
91			Decode(e) => DatabaseError::TypeError(e.to_string()),
92			PoolTimedOut => DatabaseError::ConnectionError("Pool timed out".to_string()),
93			PoolClosed => DatabaseError::ConnectionError("Pool closed".to_string()),
94			WorkerCrashed => DatabaseError::ConnectionError("Worker crashed".to_string()),
95			Migrate(e) => DatabaseError::QueryError(format!("Migration error: {}", e)),
96			_ => DatabaseError::Other(err.to_string()),
97		}
98	}
99}