1use thiserror::Error;
7
8pub type Result<T> = std::result::Result<T, Error>;
10
11#[derive(Error, Debug)]
16pub enum Error {
17 #[error("[VELES-001] Collection '{0}' already exists")]
19 CollectionExists(String),
20
21 #[error("[VELES-002] Collection '{0}' not found")]
23 CollectionNotFound(String),
24
25 #[error("[VELES-003] Point with ID '{0}' not found")]
27 PointNotFound(u64),
28
29 #[error("[VELES-004] Vector dimension mismatch: expected {expected}, got {actual}")]
31 DimensionMismatch {
32 expected: usize,
34 actual: usize,
36 },
37
38 #[error("[VELES-005] Invalid vector: {0}")]
40 InvalidVector(String),
41
42 #[error("[VELES-006] Storage error: {0}")]
44 Storage(String),
45
46 #[error("[VELES-007] Index error: {0}")]
48 Index(String),
49
50 #[error("[VELES-008] Index corrupted: {0}")]
54 IndexCorrupted(String),
55
56 #[error("[VELES-009] Configuration error: {0}")]
58 Config(String),
59
60 #[error("[VELES-010] Query error: {0}")]
64 Query(String),
65
66 #[error("[VELES-011] IO error: {0}")]
68 Io(#[from] std::io::Error),
69
70 #[error("[VELES-012] Serialization error: {0}")]
72 Serialization(String),
73
74 #[error("[VELES-013] Internal error: {0}")]
78 Internal(String),
79
80 #[error("[VELES-014] Vector not allowed on metadata-only collection '{0}'")]
82 VectorNotAllowed(String),
83
84 #[error("[VELES-015] Vector search not supported on metadata-only collection '{0}'. Use query() instead.")]
86 SearchNotSupported(String),
87
88 #[error("[VELES-016] Vector required for collection '{0}' (not metadata-only)")]
90 VectorRequired(String),
91
92 #[error("[VELES-017] Schema validation error: {0}")]
94 SchemaValidation(String),
95
96 #[error("[VELES-018] Graph operation not supported: {0}")]
98 GraphNotSupported(String),
99
100 #[error("[VELES-019] Edge with ID '{0}' already exists")]
102 EdgeExists(u64),
103
104 #[error("[VELES-020] Edge with ID '{0}' not found")]
106 EdgeNotFound(u64),
107
108 #[error("[VELES-021] Invalid edge label: {0}")]
110 InvalidEdgeLabel(String),
111
112 #[error("[VELES-022] Node with ID '{0}' not found")]
114 NodeNotFound(u64),
115
116 #[error("[VELES-023] Numeric overflow: {0}")]
121 Overflow(String),
122
123 #[error("[VELES-024] Column store error: {0}")]
127 ColumnStoreError(String),
128
129 #[error("[VELES-025] GPU error: {0}")]
133 GpuError(String),
134
135 #[error("[VELES-026] Epoch mismatch: {0}")]
140 EpochMismatch(String),
141
142 #[error("[VELES-027] Guard-rail violation: {0}")]
147 GuardRail(String),
148
149 #[error("[VELES-028] Invalid quantizer config: {0}")]
154 InvalidQuantizerConfig(String),
155
156 #[error("[VELES-029] Training failed: {0}")]
161 TrainingFailed(String),
162
163 #[error("[VELES-030] Sparse index error: {0}")]
165 SparseIndexError(String),
166}
167
168impl Error {
169 #[must_use]
171 pub const fn code(&self) -> &'static str {
172 match self {
173 Self::CollectionExists(_) => "VELES-001",
174 Self::CollectionNotFound(_) => "VELES-002",
175 Self::PointNotFound(_) => "VELES-003",
176 Self::DimensionMismatch { .. } => "VELES-004",
177 Self::InvalidVector(_) => "VELES-005",
178 Self::Storage(_) => "VELES-006",
179 Self::Index(_) => "VELES-007",
180 Self::IndexCorrupted(_) => "VELES-008",
181 Self::Config(_) => "VELES-009",
182 Self::Query(_) => "VELES-010",
183 Self::Io(_) => "VELES-011",
184 Self::Serialization(_) => "VELES-012",
185 Self::Internal(_) => "VELES-013",
186 Self::VectorNotAllowed(_) => "VELES-014",
187 Self::SearchNotSupported(_) => "VELES-015",
188 Self::VectorRequired(_) => "VELES-016",
189 Self::SchemaValidation(_) => "VELES-017",
190 Self::GraphNotSupported(_) => "VELES-018",
191 Self::EdgeExists(_) => "VELES-019",
192 Self::EdgeNotFound(_) => "VELES-020",
193 Self::InvalidEdgeLabel(_) => "VELES-021",
194 Self::NodeNotFound(_) => "VELES-022",
195 Self::Overflow(_) => "VELES-023",
196 Self::ColumnStoreError(_) => "VELES-024",
197 Self::GpuError(_) => "VELES-025",
198 Self::EpochMismatch(_) => "VELES-026",
199 Self::GuardRail(_) => "VELES-027",
200 Self::InvalidQuantizerConfig(_) => "VELES-028",
201 Self::TrainingFailed(_) => "VELES-029",
202 Self::SparseIndexError(_) => "VELES-030",
203 }
204 }
205
206 #[must_use]
210 pub const fn is_recoverable(&self) -> bool {
211 !matches!(
212 self,
213 Self::IndexCorrupted(_) | Self::Internal(_) | Self::EpochMismatch(_)
214 )
215 }
216}
217
218impl From<crate::velesql::ParseError> for Error {
220 fn from(err: crate::velesql::ParseError) -> Self {
221 Self::Query(err.to_string())
222 }
223}
224
225#[cfg(feature = "persistence")]
227impl From<crate::guardrails::GuardRailViolation> for Error {
228 fn from(v: crate::guardrails::GuardRailViolation) -> Self {
229 Self::GuardRail(v.to_string())
230 }
231}