cassandra_protocol/
error.rs

1use crate::compression::CompressionError;
2use crate::frame::message_error::ErrorBody;
3use crate::frame::Opcode;
4use crate::types::{CInt, CIntShort};
5use std::fmt::{Debug, Display};
6use std::io;
7use std::net::SocketAddr;
8use std::result;
9use std::str::Utf8Error;
10use std::string::FromUtf8Error;
11use thiserror::Error as ThisError;
12use uuid::Error as UuidError;
13
14pub type Result<T> = result::Result<T, Error>;
15
16/// CDRS custom error type. CDRS expects two types of error - errors returned by Server
17/// and internal errors occurred within the driver itself. Occasionally `io::Error`
18/// is a type that represent internal error because due to implementation IO errors only
19/// can be raised by CDRS driver. `Server` error is an error which are ones returned by
20/// a Server via result error frames.
21#[derive(Debug, ThisError)]
22#[non_exhaustive]
23pub enum Error {
24    /// Internal IO error.
25    #[error("IO error: {0}")]
26    Io(#[from] io::Error),
27    /// Internal error that may be raised during `uuid::Uuid::from_bytes`
28    #[error("Uuid parse error: {0}")]
29    UuidParse(#[from] UuidError),
30    /// General error
31    #[error("General error: {0}")]
32    General(String),
33    /// Internal error that may be raised during `String::from_utf8`
34    #[error("FromUtf8 error: {0}")]
35    FromUtf8(#[from] FromUtf8Error),
36    /// Internal error that may be raised during `str::from_utf8`
37    #[error("Utf8 error: {0}")]
38    Utf8(#[from] Utf8Error),
39    /// Internal Compression/Decompression error.
40    #[error("Compressor error: {0}")]
41    Compression(#[from] CompressionError),
42    /// Server error.
43    #[error("Server {addr} error: {body:?}")]
44    Server { body: ErrorBody, addr: SocketAddr },
45    /// Timed out waiting for an operation to complete.
46    #[error("Timeout: {0}")]
47    Timeout(String),
48    /// Unknown consistency.
49    #[error("Unknown consistency: {0}")]
50    UnknownConsistency(CIntShort),
51    /// Unknown server event.
52    #[error("Unknown server event: {0}")]
53    UnknownServerEvent(String),
54    /// Unexpected topology change event type.
55    #[error("Unexpected topology change type: {0}")]
56    UnexpectedTopologyChangeType(String),
57    /// Unexpected status change event type.
58    #[error("Unexpected status change type: {0}")]
59    UnexpectedStatusChangeType(String),
60    /// Unexpected schema change event type.
61    #[error("Unexpected schema change type: {0}")]
62    UnexpectedSchemaChangeType(String),
63    /// Unexpected schema change event target.
64    #[error("Unexpected schema change target: {0}")]
65    UnexpectedSchemaChangeTarget(String),
66    /// Unexpected additional error info.
67    #[error("Unexpected error code: {0}")]
68    UnexpectedErrorCode(CInt),
69    /// Unexpected write type.
70    #[error("Unexpected write type: {0}")]
71    UnexpectedWriteType(String),
72    /// Expected a request opcode, got something else.
73    #[error("Opcode is not a request: {0}")]
74    NonRequestOpcode(Opcode),
75    /// Expected a response opcode, got something else.
76    #[error("Opcode is not a response: {0}")]
77    NonResponseOpcode(Opcode),
78    /// Unexpected result kind.
79    #[error("Unexpected result kind: {0}")]
80    UnexpectedResultKind(CInt),
81    /// Unexpected column type.
82    #[error("Unexpected column type: {0}")]
83    UnexpectedColumnType(CIntShort),
84    /// Invalid format found for given keyspace replication strategy.
85    #[error("Invalid replication format for: {keyspace}")]
86    InvalidReplicationFormat { keyspace: String },
87    /// Unexpected response to auth message.
88    #[error("Unexpected auth response: {0}")]
89    UnexpectedAuthResponse(Opcode),
90    /// Unexpected startup response.
91    #[error("Unexpected startup response: {0}")]
92    UnexpectedStartupResponse(Opcode),
93    /// Special error for cases when starting up a connection and protocol negotiation fails. There
94    /// currently is no explicit server-side code for this, so the information must be inferred from
95    /// returned error response.
96    #[error("Invalid protocol used when communicating with a node: {0}")]
97    InvalidProtocol(SocketAddr),
98}
99
100pub fn column_is_empty_err<T: Display>(column_name: T) -> Error {
101    Error::General(format!("Column or Udt property '{column_name}' is empty"))
102}
103
104impl From<String> for Error {
105    fn from(err: String) -> Error {
106        Error::General(err)
107    }
108}
109
110impl From<&str> for Error {
111    fn from(err: &str) -> Error {
112        Error::General(err.to_string())
113    }
114}
115
116impl Clone for Error {
117    fn clone(&self) -> Self {
118        match self {
119            Error::Io(error) => Error::Io(io::Error::new(
120                error.kind(),
121                error
122                    .get_ref()
123                    .map(|error| error.to_string())
124                    .unwrap_or_default(),
125            )),
126            Error::UuidParse(error) => Error::UuidParse(error.clone()),
127            Error::General(error) => Error::General(error.clone()),
128            Error::FromUtf8(error) => Error::FromUtf8(error.clone()),
129            Error::Utf8(error) => Error::Utf8(*error),
130            Error::Compression(error) => Error::Compression(error.clone()),
131            Error::Server { body, addr } => Error::Server {
132                body: body.clone(),
133                addr: *addr,
134            },
135            Error::Timeout(error) => Error::Timeout(error.clone()),
136            Error::UnknownConsistency(value) => Error::UnknownConsistency(*value),
137            Error::UnknownServerEvent(value) => Error::UnknownServerEvent(value.clone()),
138            Error::UnexpectedTopologyChangeType(value) => {
139                Error::UnexpectedTopologyChangeType(value.clone())
140            }
141            Error::UnexpectedStatusChangeType(value) => {
142                Error::UnexpectedStatusChangeType(value.clone())
143            }
144            Error::UnexpectedSchemaChangeType(value) => {
145                Error::UnexpectedSchemaChangeType(value.clone())
146            }
147            Error::UnexpectedSchemaChangeTarget(value) => {
148                Error::UnexpectedSchemaChangeTarget(value.clone())
149            }
150            Error::UnexpectedErrorCode(value) => Error::UnexpectedErrorCode(*value),
151            Error::UnexpectedWriteType(value) => Error::UnexpectedWriteType(value.clone()),
152            Error::NonRequestOpcode(value) => Error::NonRequestOpcode(*value),
153            Error::NonResponseOpcode(value) => Error::NonResponseOpcode(*value),
154            Error::UnexpectedResultKind(value) => Error::UnexpectedResultKind(*value),
155            Error::UnexpectedColumnType(value) => Error::UnexpectedColumnType(*value),
156            Error::InvalidReplicationFormat { keyspace } => Error::InvalidReplicationFormat {
157                keyspace: keyspace.clone(),
158            },
159            Error::UnexpectedAuthResponse(value) => Error::UnexpectedAuthResponse(*value),
160            Error::UnexpectedStartupResponse(value) => Error::UnexpectedStartupResponse(*value),
161            Error::InvalidProtocol(addr) => Error::InvalidProtocol(*addr),
162        }
163    }
164}