lumosai_vector_core/
error.rs1use thiserror::Error;
4
5pub type Result<T> = std::result::Result<T, VectorError>;
7
8#[derive(Error, Debug, Clone)]
10pub enum VectorError {
11 #[error("Index '{0}' not found")]
13 IndexNotFound(String),
14
15 #[error("Index '{0}' already exists")]
16 IndexAlreadyExists(String),
17
18 #[error("Invalid index configuration: {0}")]
19 InvalidIndexConfig(String),
20
21 #[error("Vector '{0}' not found")]
23 VectorNotFound(String),
24
25 #[error("Dimension mismatch: expected {expected}, got {actual}")]
26 DimensionMismatch { expected: usize, actual: usize },
27
28 #[error("Invalid vector data: {0}")]
29 InvalidVector(String),
30
31 #[error("Embedding generation failed: {0}")]
32 EmbeddingError(String),
33
34 #[error("Invalid query: {0}")]
36 InvalidQuery(String),
37
38 #[error("Query timeout after {seconds} seconds")]
39 QueryTimeout { seconds: u64 },
40
41 #[error("Invalid filter condition: {0}")]
42 InvalidFilter(String),
43
44 #[error("Storage backend error: {0}")]
46 StorageBackend(String),
47
48 #[error("Connection failed: {0}")]
49 ConnectionFailed(String),
50
51 #[error("Authentication failed: {0}")]
52 AuthenticationFailed(String),
53
54 #[error("Permission denied: {0}")]
55 PermissionDenied(String),
56
57 #[error("Serialization error: {0}")]
59 Serialization(String),
60
61 #[error("Deserialization error: {0}")]
62 Deserialization(String),
63
64 #[error("Invalid configuration: {0}")]
66 InvalidConfig(String),
67
68 #[error("Missing required configuration: {0}")]
69 MissingConfig(String),
70
71 #[error("Resource limit exceeded: {0}")]
73 ResourceLimitExceeded(String),
74
75 #[error("Insufficient storage space")]
76 InsufficientStorage,
77
78 #[error("Memory allocation failed")]
79 OutOfMemory,
80
81 #[error("Operation not supported: {0}")]
83 NotSupported(String),
84
85 #[error("Operation failed: {0}")]
86 OperationFailed(String),
87
88 #[error("Concurrent modification detected")]
89 ConcurrentModification,
90
91 #[error("Internal error: {0}")]
93 Internal(String),
94
95 #[error("Unexpected error: {0}")]
96 Unexpected(String),
97}
98
99impl VectorError {
100 pub fn index_not_found(name: impl Into<String>) -> Self {
102 Self::IndexNotFound(name.into())
103 }
104
105 pub fn index_already_exists(name: impl Into<String>) -> Self {
107 Self::IndexAlreadyExists(name.into())
108 }
109
110 pub fn dimension_mismatch(expected: usize, actual: usize) -> Self {
112 Self::DimensionMismatch { expected, actual }
113 }
114
115 pub fn vector_not_found(id: impl Into<String>) -> Self {
117 Self::VectorNotFound(id.into())
118 }
119
120 pub fn storage_backend(msg: impl Into<String>) -> Self {
122 Self::StorageBackend(msg.into())
123 }
124
125 pub fn connection_failed(msg: impl Into<String>) -> Self {
127 Self::ConnectionFailed(msg.into())
128 }
129
130 pub fn invalid_config(msg: impl Into<String>) -> Self {
132 Self::InvalidConfig(msg.into())
133 }
134
135 pub fn serialization(msg: impl Into<String>) -> Self {
137 Self::Serialization(msg.into())
138 }
139
140 pub fn internal(msg: impl Into<String>) -> Self {
142 Self::Internal(msg.into())
143 }
144
145 pub fn embedding_error(msg: impl Into<String>) -> Self {
147 Self::EmbeddingError(msg.into())
148 }
149
150 pub fn is_retryable(&self) -> bool {
152 matches!(
153 self,
154 VectorError::QueryTimeout { .. }
155 | VectorError::ConnectionFailed(_)
156 | VectorError::InsufficientStorage
157 | VectorError::ConcurrentModification
158 )
159 }
160
161 pub fn is_client_error(&self) -> bool {
163 matches!(
164 self,
165 VectorError::IndexNotFound(_)
166 | VectorError::VectorNotFound(_)
167 | VectorError::DimensionMismatch { .. }
168 | VectorError::InvalidQuery(_)
169 | VectorError::InvalidFilter(_)
170 | VectorError::InvalidVector(_)
171 | VectorError::InvalidConfig(_)
172 | VectorError::MissingConfig(_)
173 | VectorError::NotSupported(_)
174 )
175 }
176
177 pub fn is_server_error(&self) -> bool {
179 matches!(
180 self,
181 VectorError::StorageBackend(_)
182 | VectorError::Internal(_)
183 | VectorError::Unexpected(_)
184 | VectorError::OutOfMemory
185 | VectorError::OperationFailed(_)
186 )
187 }
188}
189
190impl From<std::io::Error> for VectorError {
192 fn from(err: std::io::Error) -> Self {
193 VectorError::StorageBackend(err.to_string())
194 }
195}
196
197#[cfg(feature = "serde")]
199impl From<serde_json::Error> for VectorError {
200 fn from(err: serde_json::Error) -> Self {
201 VectorError::Serialization(err.to_string())
202 }
203}
204
205#[cfg(test)]
206mod tests {
207 use super::*;
208
209 #[test]
210 fn test_error_creation() {
211 let err = VectorError::index_not_found("test_index");
212 assert!(matches!(err, VectorError::IndexNotFound(_)));
213 assert!(err.is_client_error());
214 assert!(!err.is_retryable());
215 }
216
217 #[test]
218 fn test_dimension_mismatch() {
219 let err = VectorError::dimension_mismatch(384, 512);
220 assert!(matches!(err, VectorError::DimensionMismatch { expected: 384, actual: 512 }));
221 }
222
223 #[test]
224 fn test_error_classification() {
225 assert!(VectorError::QueryTimeout { seconds: 30 }.is_retryable());
226 assert!(VectorError::InvalidQuery("bad query".to_string()).is_client_error());
227 assert!(VectorError::Internal("system error".to_string()).is_server_error());
228 }
229}