Skip to main content

prax_sqlite/
error.rs

1//! Error types for SQLite operations.
2
3use std::fmt;
4
5use prax_query::error::QueryError;
6
7/// Result type for SQLite operations.
8pub type SqliteResult<T> = Result<T, SqliteError>;
9
10/// Error type for SQLite operations.
11#[derive(Debug)]
12pub enum SqliteError {
13    /// Pool error.
14    Pool(String),
15    /// SQLite driver error.
16    Sqlite(tokio_rusqlite::Error),
17    /// Configuration error.
18    Config(String),
19    /// Connection error.
20    Connection(String),
21    /// Query error.
22    Query(String),
23    /// Deserialization error.
24    Deserialization(String),
25    /// Type conversion error.
26    TypeConversion(String),
27    /// Timeout error.
28    Timeout(String),
29    /// Internal error.
30    Internal(String),
31}
32
33impl SqliteError {
34    /// Create a pool error.
35    pub fn pool(msg: impl Into<String>) -> Self {
36        Self::Pool(msg.into())
37    }
38
39    /// Create a configuration error.
40    pub fn config(msg: impl Into<String>) -> Self {
41        Self::Config(msg.into())
42    }
43
44    /// Create a connection error.
45    pub fn connection(msg: impl Into<String>) -> Self {
46        Self::Connection(msg.into())
47    }
48
49    /// Create a query error.
50    pub fn query(msg: impl Into<String>) -> Self {
51        Self::Query(msg.into())
52    }
53
54    /// Create a deserialization error.
55    pub fn deserialization(msg: impl Into<String>) -> Self {
56        Self::Deserialization(msg.into())
57    }
58
59    /// Create a type conversion error.
60    pub fn type_conversion(msg: impl Into<String>) -> Self {
61        Self::TypeConversion(msg.into())
62    }
63
64    /// Create a timeout error.
65    pub fn timeout(msg: impl Into<String>) -> Self {
66        Self::Timeout(msg.into())
67    }
68
69    /// Create an internal error.
70    pub fn internal(msg: impl Into<String>) -> Self {
71        Self::Internal(msg.into())
72    }
73}
74
75impl fmt::Display for SqliteError {
76    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77        match self {
78            Self::Pool(msg) => write!(f, "Pool error: {}", msg),
79            Self::Sqlite(e) => write!(f, "SQLite error: {}", e),
80            Self::Config(msg) => write!(f, "Configuration error: {}", msg),
81            Self::Connection(msg) => write!(f, "Connection error: {}", msg),
82            Self::Query(msg) => write!(f, "Query error: {}", msg),
83            Self::Deserialization(msg) => write!(f, "Deserialization error: {}", msg),
84            Self::TypeConversion(msg) => write!(f, "Type conversion error: {}", msg),
85            Self::Timeout(msg) => write!(f, "Timeout error: {}", msg),
86            Self::Internal(msg) => write!(f, "Internal error: {}", msg),
87        }
88    }
89}
90
91impl std::error::Error for SqliteError {
92    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
93        match self {
94            Self::Sqlite(e) => Some(e),
95            _ => None,
96        }
97    }
98}
99
100impl From<tokio_rusqlite::Error> for SqliteError {
101    fn from(err: tokio_rusqlite::Error) -> Self {
102        Self::Sqlite(err)
103    }
104}
105
106impl From<rusqlite::Error> for SqliteError {
107    fn from(err: rusqlite::Error) -> Self {
108        Self::Sqlite(tokio_rusqlite::Error::Rusqlite(err))
109    }
110}
111
112impl From<SqliteError> for QueryError {
113    fn from(err: SqliteError) -> Self {
114        match err {
115            SqliteError::Pool(msg) => QueryError::connection(msg),
116            SqliteError::Sqlite(e) => QueryError::database(e.to_string()),
117            SqliteError::Config(msg) => QueryError::internal(format!("config: {}", msg)),
118            SqliteError::Connection(msg) => QueryError::connection(msg),
119            SqliteError::Query(msg) => QueryError::database(msg),
120            SqliteError::Deserialization(msg) => QueryError::serialization(msg),
121            SqliteError::TypeConversion(msg) => QueryError::serialization(format!("type: {}", msg)),
122            SqliteError::Timeout(_) => QueryError::timeout(5000), // Default timeout duration
123            SqliteError::Internal(msg) => QueryError::internal(msg),
124        }
125    }
126}
127
128#[cfg(test)]
129mod tests {
130    use super::*;
131
132    #[test]
133    fn test_error_display() {
134        let err = SqliteError::config("invalid path");
135        assert!(err.to_string().contains("Configuration error"));
136        assert!(err.to_string().contains("invalid path"));
137    }
138
139    #[test]
140    fn test_error_constructors() {
141        assert!(matches!(SqliteError::pool("test"), SqliteError::Pool(_)));
142        assert!(matches!(
143            SqliteError::config("test"),
144            SqliteError::Config(_)
145        ));
146        assert!(matches!(
147            SqliteError::connection("test"),
148            SqliteError::Connection(_)
149        ));
150        assert!(matches!(SqliteError::query("test"), SqliteError::Query(_)));
151    }
152
153    #[test]
154    fn test_error_conversion() {
155        let err = SqliteError::timeout("connection timed out");
156        let query_err: QueryError = err.into();
157        assert!(query_err.is_timeout());
158    }
159}