ruvector_collections/
error.rs1use thiserror::Error;
4
5pub type Result<T> = std::result::Result<T, CollectionError>;
7
8#[derive(Debug, Error)]
10pub enum CollectionError {
11 #[error("Collection not found: {name}")]
13 CollectionNotFound {
14 name: String,
16 },
17
18 #[error("Collection already exists: {name}")]
20 CollectionAlreadyExists {
21 name: String,
23 },
24
25 #[error("Alias not found: {alias}")]
27 AliasNotFound {
28 alias: String,
30 },
31
32 #[error("Alias already exists: {alias}")]
34 AliasAlreadyExists {
35 alias: String,
37 },
38
39 #[error("Invalid configuration: {message}")]
41 InvalidConfiguration {
42 message: String,
44 },
45
46 #[error("Alias '{alias}' points to non-existent collection '{collection}'")]
48 InvalidAlias {
49 alias: String,
51 collection: String,
53 },
54
55 #[error("Cannot delete collection '{collection}' because it has active aliases: {aliases:?}")]
57 CollectionHasAliases {
58 collection: String,
60 aliases: Vec<String>,
62 },
63
64 #[error("Invalid collection name: {name} - {reason}")]
66 InvalidName {
67 name: String,
69 reason: String,
71 },
72
73 #[error("Database error: {0}")]
75 DatabaseError(#[from] ruvector_core::error::RuvectorError),
76
77 #[error("IO error: {0}")]
79 IoError(#[from] std::io::Error),
80
81 #[error("Serialization error: {0}")]
83 SerializationError(String),
84}
85
86impl From<serde_json::Error> for CollectionError {
87 fn from(err: serde_json::Error) -> Self {
88 CollectionError::SerializationError(err.to_string())
89 }
90}
91
92impl From<bincode::error::EncodeError> for CollectionError {
93 fn from(err: bincode::error::EncodeError) -> Self {
94 CollectionError::SerializationError(err.to_string())
95 }
96}
97
98impl From<bincode::error::DecodeError> for CollectionError {
99 fn from(err: bincode::error::DecodeError) -> Self {
100 CollectionError::SerializationError(err.to_string())
101 }
102}
103
104#[cfg(test)]
105mod tests {
106 use super::*;
107
108 #[test]
109 fn test_collection_not_found_display() {
110 let err = CollectionError::CollectionNotFound {
111 name: "missing".to_string(),
112 };
113 assert_eq!(err.to_string(), "Collection not found: missing");
114 }
115
116 #[test]
117 fn test_collection_already_exists_display() {
118 let err = CollectionError::CollectionAlreadyExists {
119 name: "dup".to_string(),
120 };
121 assert_eq!(err.to_string(), "Collection already exists: dup");
122 }
123
124 #[test]
125 fn test_alias_not_found_display() {
126 let err = CollectionError::AliasNotFound {
127 alias: "no_alias".to_string(),
128 };
129 assert_eq!(err.to_string(), "Alias not found: no_alias");
130 }
131
132 #[test]
133 fn test_alias_already_exists_display() {
134 let err = CollectionError::AliasAlreadyExists {
135 alias: "dup_alias".to_string(),
136 };
137 assert_eq!(err.to_string(), "Alias already exists: dup_alias");
138 }
139
140 #[test]
141 fn test_invalid_configuration_display() {
142 let err = CollectionError::InvalidConfiguration {
143 message: "bad param".to_string(),
144 };
145 assert_eq!(err.to_string(), "Invalid configuration: bad param");
146 }
147
148 #[test]
149 fn test_invalid_alias_display() {
150 let err = CollectionError::InvalidAlias {
151 alias: "a".to_string(),
152 collection: "c".to_string(),
153 };
154 assert_eq!(
155 err.to_string(),
156 "Alias 'a' points to non-existent collection 'c'"
157 );
158 }
159
160 #[test]
161 fn test_collection_has_aliases_display() {
162 let err = CollectionError::CollectionHasAliases {
163 collection: "main".to_string(),
164 aliases: vec!["a1".to_string(), "a2".to_string()],
165 };
166 let msg = err.to_string();
167 assert!(msg.contains("main"));
168 assert!(msg.contains("a1"));
169 assert!(msg.contains("a2"));
170 }
171
172 #[test]
173 fn test_invalid_name_display() {
174 let err = CollectionError::InvalidName {
175 name: "bad!".to_string(),
176 reason: "special chars".to_string(),
177 };
178 assert_eq!(
179 err.to_string(),
180 "Invalid collection name: bad! - special chars"
181 );
182 }
183
184 #[test]
185 fn test_serialization_error_display() {
186 let err = CollectionError::SerializationError("parse fail".to_string());
187 assert_eq!(err.to_string(), "Serialization error: parse fail");
188 }
189
190 #[test]
191 fn test_io_error_conversion() {
192 let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file missing");
193 let err: CollectionError = io_err.into();
194 match err {
195 CollectionError::IoError(e) => {
196 assert_eq!(e.kind(), std::io::ErrorKind::NotFound);
197 }
198 other => panic!("Expected IoError, got: {:?}", other),
199 }
200 }
201
202 #[test]
203 fn test_serde_json_error_conversion() {
204 let json_err = serde_json::from_str::<serde_json::Value>("{{bad json").unwrap_err();
205 let err: CollectionError = json_err.into();
206 match err {
207 CollectionError::SerializationError(msg) => {
208 assert!(!msg.is_empty());
209 }
210 other => panic!("Expected SerializationError, got: {:?}", other),
211 }
212 }
213
214 #[test]
215 fn test_error_is_debug() {
216 let err = CollectionError::CollectionNotFound {
217 name: "test".to_string(),
218 };
219 let debug_str = format!("{:?}", err);
220 assert!(debug_str.contains("CollectionNotFound"));
221 }
222}