1use std::error::Error;
4use std::sync::Arc;
5
6pub use super::request::{
7 auth_response::AuthResponseSerializationError,
8 batch::{BatchSerializationError, BatchStatementSerializationError},
9 execute::ExecuteSerializationError,
10 prepare::PrepareSerializationError,
11 query::{QueryParametersSerializationError, QuerySerializationError},
12 register::RegisterSerializationError,
13 startup::StartupSerializationError,
14};
15
16use super::response::CqlResponseKind;
17use super::TryFromPrimitiveError;
18use crate::utils::parse::ParseErrorCause;
19use thiserror::Error;
20
21#[derive(Error, Debug, Clone)]
33#[non_exhaustive]
34pub enum FrameBodyExtensionsParseError {
35 #[error("Frame is compressed, but no compression negotiated for connection.")]
37 NoCompressionNegotiated,
38
39 #[error("Malformed trace id: {0}")]
41 TraceIdParse(LowLevelDeserializationError),
42
43 #[error("Malformed warnings list: {0}")]
45 WarningsListParse(LowLevelDeserializationError),
46
47 #[error("Malformed custom payload map: {0}")]
49 CustomPayloadMapParse(LowLevelDeserializationError),
50
51 #[error("Snap decompression error: {0}")]
53 SnapDecompressError(Arc<dyn Error + Sync + Send>),
54
55 #[error("Error decompressing lz4 data {0}")]
57 Lz4DecompressError(Arc<dyn Error + Sync + Send>),
58}
59
60#[derive(Debug, Error)]
62#[non_exhaustive]
63pub enum FrameHeaderParseError {
64 #[error("Failed to read the frame header: {0}")]
66 HeaderIoError(std::io::Error),
67
68 #[error("Received frame marked as coming from a client")]
70 FrameFromClient,
71
72 #[error("Received frame marked as coming from the server")]
77 FrameFromServer,
78
79 #[error("Received a frame from version {0}, but only 4 is supported")]
81 VersionNotSupported(u8),
82
83 #[error("Unrecognized response opcode {0}")]
85 UnknownResponseOpcode(#[from] TryFromPrimitiveError<u8>),
86
87 #[error("Failed to read a chunk of response body. Expected {0} more bytes, error: {1}")]
89 BodyChunkIoError(usize, std::io::Error),
90
91 #[error("Connection was closed before body was read: missing {0} out of {1}")]
93 ConnectionClosed(usize, usize),
94}
95
96#[non_exhaustive]
98#[derive(Error, Debug, Clone)]
99pub enum CqlRequestSerializationError {
100 #[error("Failed to serialize STARTUP request: {0}")]
102 StartupSerialization(#[from] StartupSerializationError),
103
104 #[error("Failed to serialize REGISTER request: {0}")]
106 RegisterSerialization(#[from] RegisterSerializationError),
107
108 #[error("Failed to serialize AUTH_RESPONSE request: {0}")]
110 AuthResponseSerialization(#[from] AuthResponseSerializationError),
111
112 #[error("Failed to serialize BATCH request: {0}")]
114 BatchSerialization(#[from] BatchSerializationError),
115
116 #[error("Failed to serialize PREPARE request: {0}")]
118 PrepareSerialization(#[from] PrepareSerializationError),
119
120 #[error("Failed to serialize EXECUTE request: {0}")]
122 ExecuteSerialization(#[from] ExecuteSerializationError),
123
124 #[error("Failed to serialize QUERY request: {0}")]
126 QuerySerialization(#[from] QuerySerializationError),
127
128 #[error("Snap compression error: {0}")]
130 SnapCompressError(Arc<dyn Error + Sync + Send>),
131}
132
133#[non_exhaustive]
136#[derive(Error, Debug, Clone)]
137#[expect(clippy::enum_variant_names)]
140pub enum CqlResponseParseError {
141 #[error("Failed to deserialize ERROR response: {0}")]
142 CqlErrorParseError(#[from] CqlErrorParseError),
143 #[error("Failed to deserialize AUTH_CHALLENGE response: {0}")]
144 CqlAuthChallengeParseError(#[from] CqlAuthChallengeParseError),
145 #[error("Failed to deserialize AUTH_SUCCESS response: {0}")]
146 CqlAuthSuccessParseError(#[from] CqlAuthSuccessParseError),
147 #[error("Failed to deserialize AUTHENTICATE response: {0}")]
148 CqlAuthenticateParseError(#[from] CqlAuthenticateParseError),
149 #[error("Failed to deserialize SUPPORTED response: {0}")]
150 CqlSupportedParseError(#[from] CqlSupportedParseError),
151 #[error("Failed to deserialize EVENT response: {0}")]
152 CqlEventParseError(#[from] CqlEventParseError),
153 #[error(transparent)]
154 CqlResultParseError(#[from] CqlResultParseError),
155}
156
157impl CqlResponseParseError {
158 pub fn to_response_kind(&self) -> CqlResponseKind {
160 match self {
161 CqlResponseParseError::CqlErrorParseError(_) => CqlResponseKind::Error,
162 CqlResponseParseError::CqlAuthChallengeParseError(_) => CqlResponseKind::AuthChallenge,
163 CqlResponseParseError::CqlAuthSuccessParseError(_) => CqlResponseKind::AuthSuccess,
164 CqlResponseParseError::CqlAuthenticateParseError(_) => CqlResponseKind::Authenticate,
165 CqlResponseParseError::CqlSupportedParseError(_) => CqlResponseKind::Supported,
166 CqlResponseParseError::CqlEventParseError(_) => CqlResponseKind::Event,
167 CqlResponseParseError::CqlResultParseError(_) => CqlResponseKind::Result,
168 }
169 }
170}
171
172#[non_exhaustive]
174#[derive(Error, Debug, Clone)]
175pub enum CqlErrorParseError {
176 #[error("Malformed error code: {0}")]
177 ErrorCodeParseError(LowLevelDeserializationError),
178 #[error("Malformed error reason: {0}")]
179 ReasonParseError(LowLevelDeserializationError),
180 #[error("Malformed error field {field} of DB error {db_error}: {err}")]
181 MalformedErrorField {
182 db_error: &'static str,
183 field: &'static str,
184 err: LowLevelDeserializationError,
185 },
186}
187
188#[non_exhaustive]
190#[derive(Error, Debug, Clone)]
191pub enum CqlAuthChallengeParseError {
192 #[error("Malformed authenticate message: {0}")]
193 AuthMessageParseError(LowLevelDeserializationError),
194}
195
196#[non_exhaustive]
198#[derive(Error, Debug, Clone)]
199pub enum CqlAuthSuccessParseError {
200 #[error("Malformed success message: {0}")]
201 SuccessMessageParseError(LowLevelDeserializationError),
202}
203
204#[non_exhaustive]
206#[derive(Error, Debug, Clone)]
207pub enum CqlAuthenticateParseError {
208 #[error("Malformed authenticator name: {0}")]
209 AuthNameParseError(LowLevelDeserializationError),
210}
211
212#[non_exhaustive]
214#[derive(Error, Debug, Clone)]
215pub enum CqlSupportedParseError {
216 #[error("Malformed options map: {0}")]
217 OptionsMapDeserialization(LowLevelDeserializationError),
218}
219
220#[non_exhaustive]
222#[derive(Error, Debug, Clone)]
223pub enum CqlResultParseError {
224 #[error("Malformed RESULT response id: {0}")]
225 ResultIdParseError(LowLevelDeserializationError),
226 #[error("Unknown RESULT response id: {0}")]
227 UnknownResultId(i32),
228 #[error("RESULT:Set_keyspace response deserialization failed: {0}")]
229 SetKeyspaceParseError(#[from] SetKeyspaceParseError),
230 #[error("RESULT:Schema_change response deserialization failed: {0}")]
233 SchemaChangeParseError(#[from] SchemaChangeEventParseError),
234 #[error("RESULT:Prepared response deserialization failed: {0}")]
235 PreparedParseError(#[from] PreparedParseError),
236 #[error("RESULT:Rows response deserialization failed: {0}")]
237 RawRowsParseError(#[from] RawRowsAndPagingStateResponseParseError),
238}
239
240#[non_exhaustive]
241#[derive(Error, Debug, Clone)]
242pub enum SetKeyspaceParseError {
243 #[error("Malformed keyspace name: {0}")]
244 MalformedKeyspaceName(#[from] LowLevelDeserializationError),
245}
246
247#[non_exhaustive]
250#[derive(Error, Debug, Clone)]
251pub enum CqlEventParseError {
252 #[error("Malformed event type string: {0}")]
253 EventTypeParseError(LowLevelDeserializationError),
254 #[error("Unknown event type: {0}")]
255 UnknownEventType(String),
256 #[error("Failed to deserialize schema change event: {0}")]
257 SchemaChangeEventParseError(#[from] SchemaChangeEventParseError),
258 #[error("Failed to deserialize topology change event: {0}")]
259 TopologyChangeEventParseError(ClusterChangeEventParseError),
260 #[error("Failed to deserialize status change event: {0}")]
261 StatusChangeEventParseError(ClusterChangeEventParseError),
262}
263
264#[non_exhaustive]
267#[derive(Error, Debug, Clone)]
268pub enum SchemaChangeEventParseError {
269 #[error("Malformed schema change type string: {0}")]
270 TypeOfChangeParseError(LowLevelDeserializationError),
271 #[error("Malformed schema change target string:: {0}")]
272 TargetTypeParseError(LowLevelDeserializationError),
273 #[error("Malformed name of keyspace affected by schema change: {0}")]
274 AffectedKeyspaceParseError(LowLevelDeserializationError),
275 #[error("Malformed name of the table affected by schema change: {0}")]
276 AffectedTableNameParseError(LowLevelDeserializationError),
277 #[error("Malformed name of the target affected by schema change: {0}")]
278 AffectedTargetNameParseError(LowLevelDeserializationError),
279 #[error(
280 "Malformed number of arguments of the function/aggregate affected by schema change: {0}"
281 )]
282 ArgumentCountParseError(LowLevelDeserializationError),
283 #[error("Malformed argument of the function/aggregate affected by schema change: {0}")]
284 FunctionArgumentParseError(LowLevelDeserializationError),
285 #[error("Unknown target of schema change: {0}")]
286 UnknownTargetOfSchemaChange(String),
287}
288
289#[non_exhaustive]
291#[derive(Error, Debug, Clone)]
292pub enum ClusterChangeEventParseError {
293 #[error("Malformed type of change: {0}")]
294 TypeOfChangeParseError(LowLevelDeserializationError),
295 #[error("Malformed node address: {0}")]
296 NodeAddressParseError(LowLevelDeserializationError),
297 #[error("Unknown type of change: {0}")]
298 UnknownTypeOfChange(String),
299}
300
301#[non_exhaustive]
304#[derive(Debug, Error, Clone)]
305pub enum PreparedParseError {
306 #[error("Malformed prepared statement's id length: {0}")]
307 IdLengthParseError(LowLevelDeserializationError),
308 #[error("Invalid result metadata: {0}")]
309 ResultMetadataParseError(ResultMetadataParseError),
310 #[error("Invalid prepared metadata: {0}")]
311 PreparedMetadataParseError(PreparedMetadataParseError),
312 #[error("Non-zero paging state in result metadata: {0:?}")]
313 NonZeroPagingState(Arc<[u8]>),
314}
315
316#[non_exhaustive]
323#[derive(Debug, Error, Clone)]
324#[expect(clippy::enum_variant_names)]
327pub enum RawRowsAndPagingStateResponseParseError {
328 #[error("Malformed metadata flags: {0}")]
330 FlagsParseError(LowLevelDeserializationError),
331
332 #[error("Malformed column count: {0}")]
334 ColumnCountParseError(LowLevelDeserializationError),
335
336 #[error("Malformed paging state: {0}")]
338 PagingStateParseError(LowLevelDeserializationError),
339}
340
341#[non_exhaustive]
344#[derive(Error, Debug, Clone)]
345#[expect(clippy::enum_variant_names)]
348pub enum PreparedMetadataParseError {
349 #[error("Malformed metadata flags: {0}")]
351 FlagsParseError(LowLevelDeserializationError),
352
353 #[error("Malformed column count: {0}")]
355 ColumnCountParseError(LowLevelDeserializationError),
356
357 #[error("Malformed partition key count: {0}")]
359 PkCountParseError(LowLevelDeserializationError),
360
361 #[error("Malformed partition key index: {0}")]
363 PkIndexParseError(LowLevelDeserializationError),
364
365 #[error("Invalid global table spec: {0}")]
367 GlobalTableSpecParseError(#[from] TableSpecParseError),
368
369 #[error("Invalid column spec: {0}")]
371 ColumnSpecParseError(#[from] ColumnSpecParseError),
372}
373
374#[non_exhaustive]
377#[derive(Error, Debug, Clone)]
378pub enum ResultMetadataAndRowsCountParseError {
379 #[error("Failed to lazily deserialize result metadata: {0}")]
381 ResultMetadataParseError(#[from] ResultMetadataParseError),
382
383 #[error("Malformed rows count: {0}")]
385 RowsCountParseError(LowLevelDeserializationError),
386}
387
388#[non_exhaustive]
391#[derive(Error, Debug, Clone)]
392#[expect(clippy::enum_variant_names)]
395pub enum ResultMetadataParseError {
396 #[error("Malformed metadata flags: {0}")]
398 FlagsParseError(LowLevelDeserializationError),
399
400 #[error("Malformed column count: {0}")]
402 ColumnCountParseError(LowLevelDeserializationError),
403
404 #[error("Malformed paging state: {0}")]
406 PagingStateParseError(LowLevelDeserializationError),
407
408 #[error("Invalid global table spec: {0}")]
410 GlobalTableSpecParseError(#[from] TableSpecParseError),
411
412 #[error("Invalid column spec: {0}")]
414 ColumnSpecParseError(#[from] ColumnSpecParseError),
415}
416
417#[non_exhaustive]
420#[derive(Error, Debug, Clone)]
421pub enum TableSpecParseError {
422 #[error("Malformed keyspace name: {0}")]
423 MalformedKeyspaceName(LowLevelDeserializationError),
424 #[error("Malformed table name: {0}")]
425 MalformedTableName(LowLevelDeserializationError),
426}
427
428#[non_exhaustive]
431#[derive(Error, Debug, Clone)]
432#[error("Column spec deserialization failed, column index: {column_index}, error: {kind}")]
433pub struct ColumnSpecParseError {
434 pub column_index: usize,
435 pub kind: ColumnSpecParseErrorKind,
436}
437
438#[non_exhaustive]
441#[derive(Error, Debug, Clone)]
442#[expect(clippy::enum_variant_names)]
445pub enum ColumnSpecParseErrorKind {
446 #[error("Invalid table spec: {0}")]
447 TableSpecParseError(#[from] TableSpecParseError),
448 #[error("Malformed column name: {0}")]
449 ColumnNameParseError(#[from] LowLevelDeserializationError),
450 #[error("Invalid column type: {0}")]
451 ColumnTypeParseError(#[from] CqlTypeParseError),
452}
453
454#[non_exhaustive]
456#[derive(Error, Debug, Clone, PartialEq, Eq)]
457pub enum CustomTypeParseError {
458 #[error("Malformed simple custom type name: {0}")]
459 UnknownSimpleCustomTypeName(String),
460 #[error("Malformed complex custom type name: {0}")]
461 UnknownComplexCustomTypeName(String),
462 #[error("Unexpected character encountered: {0}, expected: {1}")]
463 UnexpectedCharacter(char, char),
464 #[error("Unable to parse an integer: {0}")]
465 IntegerParseError(ParseErrorCause),
466 #[error("Unexpected end of input")]
467 UnexpectedEndOfInput,
468 #[error("Bad hex string: {0}")]
469 BadHexString(String),
470 #[error("Bytes {0:?} do not represent a valid UTF-8 string")]
471 InvalidUtf8(Vec<u8>),
472 #[error("Wrong number of parameters {actual}, expected: {expected}")]
473 InvalidParameterCount { actual: usize, expected: usize },
474}
475
476#[non_exhaustive]
478#[derive(Error, Debug, Clone)]
479pub enum CqlTypeParseError {
480 #[error("Malformed type id: {0}")]
481 TypeIdParseError(LowLevelDeserializationError),
482 #[error("Malformed custom type name: {0}")]
483 CustomTypeNameParseError(LowLevelDeserializationError),
484 #[error("Unsupported custom type: {0}")]
485 CustomTypeUnsupported(String),
486 #[error("Malformed name of UDT keyspace: {0}")]
487 UdtKeyspaceNameParseError(LowLevelDeserializationError),
488 #[error("Malformed UDT name: {0}")]
489 UdtNameParseError(LowLevelDeserializationError),
490 #[error("Malformed UDT fields count: {0}")]
491 UdtFieldsCountParseError(LowLevelDeserializationError),
492 #[error("Malformed UDT's field name: {0}")]
493 UdtFieldNameParseError(LowLevelDeserializationError),
494 #[error("Malformed tuple length: {0}")]
495 TupleLengthParseError(LowLevelDeserializationError),
496 #[error("CQL Type not yet implemented, id: {0}")]
497 TypeNotImplemented(u16),
498 #[error("Failed to parse custom CQL type: {0}")]
499 CustomTypeParseError(CustomTypeParseError),
500}
501
502#[non_exhaustive]
513#[derive(Error, Debug, Clone)]
514pub enum LowLevelDeserializationError {
515 #[error(transparent)]
516 IoError(Arc<std::io::Error>),
517 #[error(transparent)]
518 TryFromIntError(#[from] std::num::TryFromIntError),
519 #[error(transparent)]
520 TryFromSliceError(#[from] std::array::TryFromSliceError),
521 #[error("Not enough bytes! expected: {expected}, received: {received}")]
522 TooFewBytesReceived { expected: usize, received: usize },
523 #[error("Invalid value length: {0}")]
524 InvalidValueLength(i32),
525 #[error("Unknown consistency: {0}")]
526 UnknownConsistency(#[from] TryFromPrimitiveError<u16>),
527 #[error("Invalid inet bytes length: {0}. Accepted lengths are 4 and 16 bytes.")]
528 InvalidInetLength(u8),
529 #[error("UTF8 deserialization failed: {0}")]
530 UTF8DeserializationError(#[from] std::str::Utf8Error),
531}
532
533impl From<std::io::Error> for LowLevelDeserializationError {
534 fn from(value: std::io::Error) -> Self {
535 Self::IoError(Arc::new(value))
536 }
537}