1use std::fmt;
4
5use prax_query::error::QueryError;
6
7pub type SqliteResult<T> = Result<T, SqliteError>;
9
10#[derive(Debug)]
12pub enum SqliteError {
13 Pool(String),
15 Sqlite(tokio_rusqlite::Error),
17 Config(String),
19 Connection(String),
21 Query(String),
23 Deserialization(String),
25 TypeConversion(String),
27 Timeout(String),
29 Internal(String),
31 #[cfg(feature = "vector")]
33 Vector(crate::vector::error::VectorError),
34}
35
36impl SqliteError {
37 pub fn pool(msg: impl Into<String>) -> Self {
39 Self::Pool(msg.into())
40 }
41
42 pub fn config(msg: impl Into<String>) -> Self {
44 Self::Config(msg.into())
45 }
46
47 pub fn connection(msg: impl Into<String>) -> Self {
49 Self::Connection(msg.into())
50 }
51
52 pub fn query(msg: impl Into<String>) -> Self {
54 Self::Query(msg.into())
55 }
56
57 pub fn deserialization(msg: impl Into<String>) -> Self {
59 Self::Deserialization(msg.into())
60 }
61
62 pub fn type_conversion(msg: impl Into<String>) -> Self {
64 Self::TypeConversion(msg.into())
65 }
66
67 pub fn timeout(msg: impl Into<String>) -> Self {
69 Self::Timeout(msg.into())
70 }
71
72 pub fn internal(msg: impl Into<String>) -> Self {
74 Self::Internal(msg.into())
75 }
76}
77
78impl fmt::Display for SqliteError {
79 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80 match self {
81 Self::Pool(msg) => write!(f, "Pool error: {}", msg),
82 Self::Sqlite(e) => write!(f, "SQLite error: {}", e),
83 Self::Config(msg) => write!(f, "Configuration error: {}", msg),
84 Self::Connection(msg) => write!(f, "Connection error: {}", msg),
85 Self::Query(msg) => write!(f, "Query error: {}", msg),
86 Self::Deserialization(msg) => write!(f, "Deserialization error: {}", msg),
87 Self::TypeConversion(msg) => write!(f, "Type conversion error: {}", msg),
88 Self::Timeout(msg) => write!(f, "Timeout error: {}", msg),
89 Self::Internal(msg) => write!(f, "Internal error: {}", msg),
90 #[cfg(feature = "vector")]
91 Self::Vector(e) => write!(f, "Vector error: {}", e),
92 }
93 }
94}
95
96impl std::error::Error for SqliteError {
97 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
98 match self {
99 Self::Sqlite(e) => Some(e),
100 #[cfg(feature = "vector")]
101 Self::Vector(e) => Some(e),
102 _ => None,
103 }
104 }
105}
106
107impl From<tokio_rusqlite::Error> for SqliteError {
108 fn from(err: tokio_rusqlite::Error) -> Self {
109 Self::Sqlite(err)
110 }
111}
112
113impl From<rusqlite::Error> for SqliteError {
114 fn from(err: rusqlite::Error) -> Self {
115 Self::Sqlite(tokio_rusqlite::Error::Rusqlite(err))
116 }
117}
118
119#[cfg(feature = "vector")]
120impl From<crate::vector::error::VectorError> for SqliteError {
121 fn from(err: crate::vector::error::VectorError) -> Self {
122 Self::Vector(err)
123 }
124}
125
126impl From<SqliteError> for QueryError {
127 fn from(err: SqliteError) -> Self {
128 match err {
129 SqliteError::Pool(msg) => QueryError::connection(msg),
130 SqliteError::Sqlite(e) => QueryError::database(e.to_string()),
131 SqliteError::Config(msg) => QueryError::internal(format!("config: {}", msg)),
132 SqliteError::Connection(msg) => QueryError::connection(msg),
133 SqliteError::Query(msg) => QueryError::database(msg),
134 SqliteError::Deserialization(msg) => QueryError::serialization(msg),
135 SqliteError::TypeConversion(msg) => QueryError::serialization(format!("type: {}", msg)),
136 SqliteError::Timeout(msg) => {
137 QueryError::timeout(5000).with_context(format!("SQLite reported: {}", msg))
141 }
142 SqliteError::Internal(msg) => QueryError::internal(msg),
143 #[cfg(feature = "vector")]
144 SqliteError::Vector(e) => QueryError::database(e.to_string()),
145 }
146 }
147}
148
149#[cfg(test)]
150mod tests {
151 use super::*;
152
153 #[test]
154 fn test_error_display() {
155 let err = SqliteError::config("invalid path");
156 assert!(err.to_string().contains("Configuration error"));
157 assert!(err.to_string().contains("invalid path"));
158 }
159
160 #[test]
161 fn test_error_constructors() {
162 assert!(matches!(SqliteError::pool("test"), SqliteError::Pool(_)));
163 assert!(matches!(
164 SqliteError::config("test"),
165 SqliteError::Config(_)
166 ));
167 assert!(matches!(
168 SqliteError::connection("test"),
169 SqliteError::Connection(_)
170 ));
171 assert!(matches!(SqliteError::query("test"), SqliteError::Query(_)));
172 }
173
174 #[test]
175 fn test_error_conversion() {
176 let err = SqliteError::timeout("connection timed out");
177 let query_err: QueryError = err.into();
178 assert!(query_err.is_timeout());
179 }
180}