clickhouse_readonly/
error.rs

1use std::borrow::Cow;
2use std::io;
3use std::result;
4use std::str::Utf8Error;
5use std::string::FromUtf8Error;
6
7use thiserror::Error;
8use tokio::time::error::Elapsed;
9use url::ParseError;
10
11/// Result type alias for this library for ConnectionError.
12pub type ConnectionResult<T> = result::Result<T, ConnectionError>;
13/// Result type alias for this library.
14pub type Result<T> = result::Result<T, Error>;
15
16/// This type enumerates library errors.
17#[derive(Debug, Error)]
18pub enum Error {
19    #[error("Driver error: `{}`", _0)]
20    Driver(#[source] DriverError),
21
22    #[error("Input/output error: `{}`", _0)]
23    IO(#[source] io::Error),
24
25    #[error("Connections error: `{}`", _0)]
26    Connection(#[source] ConnectionError),
27
28    #[error("Other error: `{}`", _0)]
29    Other(Cow<'static, str>),
30
31    #[error("Server error: `{}`", _0)]
32    Server(#[source] ServerError),
33
34    #[error("URL error: `{}`", _0)]
35    Url(#[source] UrlError),
36
37    #[error("From SQL error: `{}`", _0)]
38    FromSql(#[source] FromSqlError),
39}
40
41/// This type represents Clickhouse server error.
42#[derive(Debug, Error, Clone)]
43#[error("ERROR {} ({:?}): {}", name, code, message)]
44pub struct ServerError {
45    pub code: u32,
46    pub name: String,
47    pub message: String,
48    pub stack_trace: String,
49}
50
51/// This type enumerates connection errors.
52#[derive(Debug, Error)]
53pub enum ConnectionError {
54    #[error("TLS connection requires hostname to be provided")]
55    TlsHostNotProvided,
56
57    #[error("Input/output error: `{}`", _0)]
58    IOError(#[source] io::Error),
59
60    #[error("TLS connection error: `{}`", _0)]
61    TlsError(#[source] tokio_native_tls::native_tls::Error),
62}
63
64/// This type enumerates connection URL errors.
65#[derive(Debug, Error, Clone)]
66pub enum UrlError {
67    #[error("Invalid or incomplete connection URL")]
68    Invalid,
69
70    #[error("Invalid value `{}' for connection URL parameter `{}'", value, param)]
71    InvalidParamValue { param: String, value: String },
72
73    #[error("URL parse error: {}", _0)]
74    Parse(#[source] ParseError),
75
76    #[error("Unknown connection URL parameter `{}'", param)]
77    UnknownParameter { param: String },
78
79    #[error("Unsupported connection URL scheme `{}'", scheme)]
80    UnsupportedScheme { scheme: String },
81}
82
83/// This type enumerates driver errors.
84#[derive(Debug, Error, Clone)]
85pub enum DriverError {
86    #[error("Varint overflows a 64-bit integer.")]
87    Overflow,
88
89    #[error("Unknown packet 0x{:x}.", packet)]
90    UnknownPacket { packet: u64 },
91
92    #[error("Unexpected packet.")]
93    UnexpectedPacket,
94
95    #[error("Timeout error.")]
96    Timeout,
97
98    #[error("Invalid utf-8 sequence.")]
99    Utf8Error(Utf8Error),
100
101    #[error("UnknownSetting name {}", name)]
102    UnknownSetting { name: String },
103}
104
105/// This type enumerates cast from sql type errors.
106#[derive(Debug, Error, Clone)]
107pub enum FromSqlError {
108    #[error("SqlType::{} cannot be cast to {}.", src, dst)]
109    InvalidType {
110        src: Cow<'static, str>,
111        dst: Cow<'static, str>,
112    },
113
114    #[error("Out of range.")]
115    OutOfRange,
116
117    #[error("Unsupported operation.")]
118    UnsupportedOperation,
119
120    #[error("Unsupported column type `{0}`.")]
121    UnsupportedColumnType(Cow<'static, str>),
122}
123
124impl Error {
125    pub(crate) fn is_would_block(&self) -> bool {
126        if let Error::IO(ref e) = self {
127            if e.kind() == io::ErrorKind::WouldBlock {
128                return true;
129            }
130        }
131        false
132    }
133}
134
135impl From<ConnectionError> for Error {
136    fn from(error: ConnectionError) -> Self {
137        Error::Connection(error)
138    }
139}
140
141impl From<tokio_native_tls::native_tls::Error> for ConnectionError {
142    fn from(error: tokio_native_tls::native_tls::Error) -> Self {
143        ConnectionError::TlsError(error)
144    }
145}
146
147impl From<DriverError> for Error {
148    fn from(err: DriverError) -> Self {
149        Error::Driver(err)
150    }
151}
152
153impl From<io::Error> for Error {
154    fn from(err: io::Error) -> Self {
155        Error::IO(err)
156    }
157}
158
159impl From<Error> for io::Error {
160    fn from(err: Error) -> Self {
161        match err {
162            Error::IO(error) => error,
163            e => io::Error::new(io::ErrorKind::Other, e.to_string()),
164        }
165    }
166}
167
168impl From<ServerError> for Error {
169    fn from(err: ServerError) -> Self {
170        Error::Server(err)
171    }
172}
173
174impl From<UrlError> for Error {
175    fn from(err: UrlError) -> Self {
176        Error::Url(err)
177    }
178}
179
180impl From<String> for Error {
181    fn from(err: String) -> Self {
182        Error::Other(Cow::from(err))
183    }
184}
185
186impl From<&str> for Error {
187    fn from(err: &str) -> Self {
188        Error::Other(err.to_string().into())
189    }
190}
191
192impl From<FromUtf8Error> for Error {
193    fn from(err: FromUtf8Error) -> Self {
194        Error::Other(err.to_string().into())
195    }
196}
197
198impl From<Elapsed> for Error {
199    fn from(_err: Elapsed) -> Self {
200        Error::Driver(DriverError::Timeout)
201    }
202}
203
204impl From<ParseError> for Error {
205    fn from(err: ParseError) -> Self {
206        Error::Url(UrlError::Parse(err))
207    }
208}
209
210impl From<Utf8Error> for Error {
211    fn from(err: Utf8Error) -> Self {
212        Error::Driver(DriverError::Utf8Error(err))
213    }
214}
215
216impl Error {
217    pub fn exception_name(&self) -> &str {
218        match self {
219            Error::Driver(_) => "DriverException",
220            Error::IO(_) => "IOException",
221            Error::Connection(_) => "ConnectionException",
222            Error::Other(_) => "OtherException",
223            Error::Server(e) => e.name.as_str(),
224            Error::Url(_) => "URLException",
225            Error::FromSql(_) => "SQLException",
226        }
227    }
228}