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::TryFromPrimitiveError;
17use super::response::CqlResponseKind;
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 #[error("RESULT:Rows result metadata response deserialization failed: {0}")]
239 ResultMetadataParseError(#[from] ResultMetadataAndRowsCountParseError),
240}
241
242#[non_exhaustive]
243#[derive(Error, Debug, Clone)]
244pub enum SetKeyspaceParseError {
245 #[error("Malformed keyspace name: {0}")]
246 MalformedKeyspaceName(#[from] LowLevelDeserializationError),
247}
248
249#[non_exhaustive]
252#[derive(Error, Debug, Clone)]
253pub enum CqlEventParseError {
254 #[error("Malformed event type string: {0}")]
255 EventTypeParseError(LowLevelDeserializationError),
256 #[error("Unknown event type: {0}")]
257 UnknownEventType(String),
258 #[error("Failed to deserialize schema change event: {0}")]
259 SchemaChangeEventParseError(#[from] SchemaChangeEventParseError),
260 #[error("Failed to deserialize topology change event: {0}")]
261 TopologyChangeEventParseError(ClusterChangeEventParseError),
262 #[error("Failed to deserialize status change event: {0}")]
263 StatusChangeEventParseError(ClusterChangeEventParseError),
264 #[error("Failed to deserialize client routes change event: {0}")]
265 ClientRoutesChangeEventParseError(ClientRoutesChangeEventParseError),
266}
267
268#[non_exhaustive]
271#[derive(Error, Debug, Clone)]
272pub enum SchemaChangeEventParseError {
273 #[error("Malformed schema change type string: {0}")]
274 TypeOfChangeParseError(LowLevelDeserializationError),
275 #[error("Malformed schema change target string:: {0}")]
276 TargetTypeParseError(LowLevelDeserializationError),
277 #[error("Malformed name of keyspace affected by schema change: {0}")]
278 AffectedKeyspaceParseError(LowLevelDeserializationError),
279 #[error("Malformed name of the table affected by schema change: {0}")]
280 AffectedTableNameParseError(LowLevelDeserializationError),
281 #[error("Malformed name of the target affected by schema change: {0}")]
282 AffectedTargetNameParseError(LowLevelDeserializationError),
283 #[error(
284 "Malformed number of arguments of the function/aggregate affected by schema change: {0}"
285 )]
286 ArgumentCountParseError(LowLevelDeserializationError),
287 #[error("Malformed argument of the function/aggregate affected by schema change: {0}")]
288 FunctionArgumentParseError(LowLevelDeserializationError),
289 #[error("Unknown target of schema change: {0}")]
290 UnknownTargetOfSchemaChange(String),
291}
292
293#[non_exhaustive]
295#[derive(Error, Debug, Clone)]
296pub enum ClusterChangeEventParseError {
297 #[error("Malformed type of change: {0}")]
298 TypeOfChangeParseError(LowLevelDeserializationError),
299 #[error("Malformed node address: {0}")]
300 NodeAddressParseError(LowLevelDeserializationError),
301 #[error("Unknown type of change: {0}")]
302 UnknownTypeOfChange(String),
303}
304
305#[non_exhaustive]
307#[derive(Error, Debug, Clone)]
308pub enum ClientRoutesChangeEventParseError {
309 #[error("Malformed type of change: {0}")]
310 TypeOfChangeParseError(LowLevelDeserializationError),
311 #[error("Unknown type of change: {0}")]
312 UnknownTypeOfChange(String),
313 #[error("Malformed connection ids: {0}")]
314 ConnectionIdsParseError(LowLevelDeserializationError),
315 #[error("Malformed host ids: {0}")]
316 HostIdsParseError(LowLevelDeserializationError),
317 #[error("Unable to parse host id as UUID: {0}")]
318 HostIdsUuidParseError(uuid::Error),
319 #[error(
320 "Connection and host ids length mismatch: there are {connection_ids_count} connection ids and {host_ids_count} host ids"
321 )]
322 ConnectionHostIdsLengthMismatch {
323 connection_ids_count: usize,
324 host_ids_count: usize,
325 },
326}
327
328#[non_exhaustive]
331#[derive(Debug, Error, Clone)]
332pub enum PreparedParseError {
333 #[error("Malformed prepared statement's id length: {0}")]
335 IdLengthParseError(LowLevelDeserializationError),
336 #[error("Malformed prepared statement's id: {0}")]
337 IdParseError(LowLevelDeserializationError),
338 #[error("Malformed prepared statement's result metadata id: {0}")]
339 ResultMetadataIdParseError(LowLevelDeserializationError),
340 #[error("Invalid result metadata: {0}")]
341 ResultMetadataParseError(ResultMetadataParseError),
342 #[error("Invalid prepared metadata: {0}")]
343 PreparedMetadataParseError(PreparedMetadataParseError),
344 #[error("Non-zero paging state in result metadata: {0:?}")]
345 NonZeroPagingState(Arc<[u8]>),
346}
347
348#[non_exhaustive]
355#[derive(Debug, Error, Clone)]
356pub enum RawRowsAndPagingStateResponseParseError {
358 #[error("Malformed metadata flags: {0}")]
360 FlagsParseError(LowLevelDeserializationError),
361
362 #[error("Malformed column count: {0}")]
364 ColumnCountParseError(LowLevelDeserializationError),
365
366 #[error("Malformed paging state: {0}")]
368 PagingStateParseError(LowLevelDeserializationError),
369
370 #[error("Metadata_changed and No_metadata flags are both present")]
371 IdPresentForEmptyMetadata,
372}
373
374#[non_exhaustive]
377#[derive(Error, Debug, Clone)]
378#[expect(clippy::enum_variant_names)]
381pub enum PreparedMetadataParseError {
382 #[error("Malformed metadata flags: {0}")]
384 FlagsParseError(LowLevelDeserializationError),
385
386 #[error("Malformed column count: {0}")]
388 ColumnCountParseError(LowLevelDeserializationError),
389
390 #[error("Malformed partition key count: {0}")]
392 PkCountParseError(LowLevelDeserializationError),
393
394 #[error("Malformed partition key index: {0}")]
396 PkIndexParseError(LowLevelDeserializationError),
397
398 #[error("Invalid global table spec: {0}")]
400 GlobalTableSpecParseError(#[from] TableSpecParseError),
401
402 #[error("Invalid column spec: {0}")]
404 ColumnSpecParseError(#[from] ColumnSpecParseError),
405}
406
407#[non_exhaustive]
410#[derive(Error, Debug, Clone)]
411pub enum ResultMetadataAndRowsCountParseError {
412 #[error("Failed to lazily deserialize result metadata: {0}")]
414 ResultMetadataParseError(#[from] ResultMetadataParseError),
415
416 #[error("Malformed rows count: {0}")]
418 RowsCountParseError(LowLevelDeserializationError),
419}
420
421#[non_exhaustive]
424#[derive(Error, Debug, Clone)]
425pub enum ResultMetadataParseError {
427 #[error("Malformed metadata flags: {0}")]
429 FlagsParseError(LowLevelDeserializationError),
430
431 #[error("Malformed column count: {0}")]
433 ColumnCountParseError(LowLevelDeserializationError),
434
435 #[error("Malformed paging state: {0}")]
437 PagingStateParseError(LowLevelDeserializationError),
438
439 #[error("Malformed new metadata id: {0}")]
441 NewMetadataIdParseError(LowLevelDeserializationError),
442
443 #[error("Invalid global table spec: {0}")]
445 GlobalTableSpecParseError(#[from] TableSpecParseError),
446
447 #[error("Invalid column spec: {0}")]
449 ColumnSpecParseError(#[from] ColumnSpecParseError),
450
451 #[error("Metadata_changed and No_metadata flags are both present")]
452 IdPresentForEmptyMetadata,
453}
454
455#[non_exhaustive]
458#[derive(Error, Debug, Clone)]
459pub enum TableSpecParseError {
460 #[error("Malformed keyspace name: {0}")]
461 MalformedKeyspaceName(LowLevelDeserializationError),
462 #[error("Malformed table name: {0}")]
463 MalformedTableName(LowLevelDeserializationError),
464}
465
466#[non_exhaustive]
469#[derive(Error, Debug, Clone)]
470#[error("Column spec deserialization failed, column index: {column_index}, error: {kind}")]
471pub struct ColumnSpecParseError {
472 pub column_index: usize,
473 pub kind: ColumnSpecParseErrorKind,
474}
475
476#[non_exhaustive]
479#[derive(Error, Debug, Clone)]
480#[expect(clippy::enum_variant_names)]
483pub enum ColumnSpecParseErrorKind {
484 #[error("Invalid table spec: {0}")]
485 TableSpecParseError(#[from] TableSpecParseError),
486 #[error("Malformed column name: {0}")]
487 ColumnNameParseError(#[from] LowLevelDeserializationError),
488 #[error("Invalid column type: {0}")]
489 ColumnTypeParseError(#[from] CqlTypeParseError),
490}
491
492#[non_exhaustive]
494#[derive(Error, Debug, Clone, PartialEq, Eq)]
495pub enum CustomTypeParseError {
496 #[error("Malformed simple custom type name: {0}")]
497 UnknownSimpleCustomTypeName(String),
498 #[error("Malformed complex custom type name: {0}")]
499 UnknownComplexCustomTypeName(String),
500 #[error("Unexpected character encountered: {0}, expected: {1}")]
501 UnexpectedCharacter(char, char),
502 #[error("Unable to parse an integer: {0}")]
503 IntegerParseError(ParseErrorCause),
504 #[error("Unexpected end of input")]
505 UnexpectedEndOfInput,
506 #[error("Bad hex string: {0}")]
507 BadHexString(String),
508 #[error("Bytes {0:?} do not represent a valid UTF-8 string")]
509 InvalidUtf8(Vec<u8>),
510 #[error("Wrong number of parameters {actual}, expected: {expected}")]
511 InvalidParameterCount { actual: usize, expected: usize },
512}
513
514#[non_exhaustive]
516#[derive(Error, Debug, Clone)]
517pub enum CqlTypeParseError {
518 #[error("Malformed type id: {0}")]
519 TypeIdParseError(LowLevelDeserializationError),
520 #[error("Malformed custom type name: {0}")]
521 CustomTypeNameParseError(LowLevelDeserializationError),
522 #[error("Unsupported custom type: {0}")]
523 CustomTypeUnsupported(String),
524 #[error("Malformed name of UDT keyspace: {0}")]
525 UdtKeyspaceNameParseError(LowLevelDeserializationError),
526 #[error("Malformed UDT name: {0}")]
527 UdtNameParseError(LowLevelDeserializationError),
528 #[error("Malformed UDT fields count: {0}")]
529 UdtFieldsCountParseError(LowLevelDeserializationError),
530 #[error("Malformed UDT's field name: {0}")]
531 UdtFieldNameParseError(LowLevelDeserializationError),
532 #[error("Malformed tuple length: {0}")]
533 TupleLengthParseError(LowLevelDeserializationError),
534 #[error("CQL Type not yet implemented, id: {0}")]
535 TypeNotImplemented(u16),
536 #[error("Failed to parse custom CQL type: {0}")]
537 CustomTypeParseError(CustomTypeParseError),
538}
539
540#[non_exhaustive]
551#[derive(Error, Debug, Clone)]
552pub enum LowLevelDeserializationError {
553 #[error(transparent)]
554 IoError(Arc<std::io::Error>),
555 #[error(transparent)]
556 TryFromIntError(#[from] std::num::TryFromIntError),
557 #[error(transparent)]
558 TryFromSliceError(#[from] std::array::TryFromSliceError),
559 #[error("Not enough bytes! expected: {expected}, received: {received}")]
560 TooFewBytesReceived { expected: usize, received: usize },
561 #[error("Invalid value length: {0}")]
562 InvalidValueLength(i32),
563 #[error("Unknown consistency: {0}")]
564 UnknownConsistency(#[from] TryFromPrimitiveError<u16>),
565 #[error("Invalid inet bytes length: {0}. Accepted lengths are 4 and 16 bytes.")]
566 InvalidInetLength(u8),
567 #[error("UTF8 deserialization failed: {0}")]
568 UTF8DeserializationError(#[from] std::str::Utf8Error),
569}
570
571impl From<std::io::Error> for LowLevelDeserializationError {
572 fn from(value: std::io::Error) -> Self {
573 Self::IoError(Arc::new(value))
574 }
575}