sqlx_exasol_impl/
error.rs

1use std::fmt::{Debug, Display};
2
3use async_tungstenite::tungstenite::{protocol::CloseFrame, Error as WsError};
4use rsa::errors::Error as RsaError;
5use serde_json::error::Error as JsonError;
6use thiserror::Error as ThisError;
7
8use crate::SqlxError;
9
10/// Enum representing protocol implementation errors.
11#[derive(Debug, ThisError)]
12pub enum ExaProtocolError {
13    #[error("JSON error: {0}")]
14    Json(#[from] JsonError),
15    #[error("expected {0} parameter sets; found a mismatch of length {1}")]
16    ParameterLengthMismatch(usize, usize),
17    #[error("transaction already open")]
18    TransactionAlreadyOpen,
19    #[error("not ready to send data")]
20    SendNotReady,
21    #[error("no response received")]
22    NoResponse,
23    #[error("server closed connection; info: {0}")]
24    WebSocketClosed(CloseError),
25    #[error("feature 'compression' must be enabled to use compression")]
26    CompressionDisabled,
27}
28
29#[derive(Debug)]
30pub struct CloseError(Option<CloseFrame>);
31
32impl Display for CloseError {
33    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34        match &self.0 {
35            Some(c) => write!(f, "{c}"),
36            None => write!(f, "unknown reason"),
37        }
38    }
39}
40
41impl From<Option<CloseFrame>> for ExaProtocolError {
42    fn from(value: Option<CloseFrame>) -> Self {
43        Self::WebSocketClosed(CloseError(value))
44    }
45}
46
47impl From<ExaProtocolError> for SqlxError {
48    fn from(value: ExaProtocolError) -> Self {
49        Self::Protocol(value.to_string())
50    }
51}
52
53/// Helper trait used for converting errors from various underlying libraries to `SQLx`.
54pub trait ToSqlxError {
55    fn to_sqlx_err(self) -> SqlxError;
56}
57
58impl ToSqlxError for WsError {
59    fn to_sqlx_err(self) -> SqlxError {
60        match self {
61            WsError::ConnectionClosed => SqlxError::Protocol(WsError::ConnectionClosed.to_string()),
62            WsError::AlreadyClosed => SqlxError::Protocol(WsError::AlreadyClosed.to_string()),
63            WsError::Io(e) => SqlxError::Io(e),
64            WsError::Tls(e) => SqlxError::Tls(e.into()),
65            WsError::Capacity(e) => SqlxError::Protocol(e.to_string()),
66            WsError::Protocol(e) => SqlxError::Protocol(e.to_string()),
67            WsError::WriteBufferFull(e) => SqlxError::Protocol(e.to_string()),
68            WsError::Utf8 => SqlxError::Protocol(WsError::Utf8.to_string()),
69            WsError::Url(e) => SqlxError::Configuration(e.into()),
70            WsError::Http(r) => SqlxError::Protocol(format!("HTTP error: {}", r.status())),
71            WsError::HttpFormat(e) => SqlxError::Protocol(e.to_string()),
72            WsError::AttackAttempt => SqlxError::Tls(WsError::AttackAttempt.into()),
73        }
74    }
75}
76
77impl ToSqlxError for RsaError {
78    fn to_sqlx_err(self) -> SqlxError {
79        SqlxError::Protocol(self.to_string())
80    }
81}