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