databend_driver_core/
error.rs1use std::sync::LazyLock;
16
17static ERROR_VERSION_SUFFIX: LazyLock<bool> =
18 LazyLock::new(|| std::env::var("BENDSQL_ERROR_NO_VERSION").is_err());
19
20#[derive(Debug)]
21pub struct ConvertError {
22 target: &'static str,
23 data: String,
24 message: Option<String>,
25}
26
27impl ConvertError {
28 pub fn new(target: &'static str, data: String) -> Self {
29 ConvertError {
30 target,
31 data,
32 message: None,
33 }
34 }
35
36 pub fn with_message(mut self, message: String) -> Self {
37 self.message = Some(message);
38 self
39 }
40}
41
42#[derive(Debug)]
43pub enum Error {
44 Parsing(String),
45 Protocol(String),
46 Transport(String),
47 IO(String),
48 BadArgument(String),
49 InvalidResponse(String),
50 Api(databend_client::Error),
51 Arrow(arrow_schema::ArrowError),
52 Convert(ConvertError),
53}
54
55impl Error {
56 fn formatted_message(&self) -> String {
57 match self {
58 Error::Parsing(msg) => format!("ParseError: {msg}"),
59 Error::Protocol(msg) => format!("ProtocolError: {msg}"),
60 Error::Transport(msg) => format!("TransportError: {msg}"),
61 Error::IO(msg) => format!("IOError: {msg}"),
62 Error::BadArgument(msg) => format!("BadArgument: {msg}"),
63 Error::InvalidResponse(msg) => format!("ResponseError: {msg}"),
64 Error::Arrow(e) => {
65 let msg = match e {
66 arrow_schema::ArrowError::IoError(msg, _) => {
67 static START: &str = "Code:";
68 static END: &str = ". at";
69
70 let message_index = msg.find(START).unwrap_or(0);
71 let message_end_index = msg.find(END).unwrap_or(msg.len());
72 let message = &msg[message_index..message_end_index];
73 message.replace("\\n", "\n")
74 }
75 other => format!("{other}"),
76 };
77 format!("ArrowError: {msg}")
78 }
79 Error::Convert(e) => format!(
80 "ConvertError: cannot convert {} to {}: {:?}",
81 e.data, e.target, e.message
82 ),
83 Error::Api(e) => format!("APIError: {e}"),
84 }
85 }
86}
87
88impl std::fmt::Display for Error {
89 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90 let msg = self.formatted_message();
91 if *ERROR_VERSION_SUFFIX {
92 write!(f, "{msg} [v{}]", env!("CARGO_PKG_VERSION"))
93 } else {
94 write!(f, "{msg}")
95 }
96 }
97}
98
99impl std::error::Error for Error {}
100
101pub type Result<T, E = Error> = core::result::Result<T, E>;
102
103impl From<url::ParseError> for Error {
104 fn from(e: url::ParseError) -> Self {
105 Error::Parsing(e.to_string())
106 }
107}
108
109impl From<std::num::ParseIntError> for Error {
110 fn from(e: std::num::ParseIntError) -> Self {
111 Error::Parsing(e.to_string())
112 }
113}
114
115impl From<std::str::ParseBoolError> for Error {
116 fn from(e: std::str::ParseBoolError) -> Self {
117 Error::Parsing(e.to_string())
118 }
119}
120
121impl From<std::num::ParseFloatError> for Error {
122 fn from(e: std::num::ParseFloatError) -> Self {
123 Error::Parsing(e.to_string())
124 }
125}
126
127impl From<chrono::ParseError> for Error {
128 fn from(e: chrono::ParseError) -> Self {
129 Error::Parsing(e.to_string())
130 }
131}
132
133impl From<std::io::Error> for Error {
134 fn from(e: std::io::Error) -> Self {
135 Error::IO(e.to_string())
136 }
137}
138
139impl From<glob::GlobError> for Error {
140 fn from(e: glob::GlobError) -> Self {
141 Error::IO(e.to_string())
142 }
143}
144
145impl From<glob::PatternError> for Error {
146 fn from(e: glob::PatternError) -> Self {
147 Error::Parsing(e.to_string())
148 }
149}
150
151#[cfg(feature = "flight-sql")]
152impl From<tonic::Status> for Error {
153 fn from(e: tonic::Status) -> Self {
154 Error::Protocol(e.to_string())
155 }
156}
157
158#[cfg(feature = "flight-sql")]
159impl From<tonic::transport::Error> for Error {
160 fn from(e: tonic::transport::Error) -> Self {
161 Error::Transport(e.to_string())
162 }
163}
164
165impl From<arrow_schema::ArrowError> for Error {
166 fn from(e: arrow_schema::ArrowError) -> Self {
167 Error::Arrow(e)
168 }
169}
170
171impl From<std::str::Utf8Error> for Error {
172 fn from(e: std::str::Utf8Error) -> Self {
173 Error::Parsing(e.to_string())
174 }
175}
176
177impl From<std::string::FromUtf8Error> for Error {
178 fn from(e: std::string::FromUtf8Error) -> Self {
179 Error::Parsing(e.to_string())
180 }
181}
182
183impl From<serde_json::Error> for Error {
184 fn from(e: serde_json::Error) -> Self {
185 Error::Parsing(e.to_string())
186 }
187}
188
189impl From<jiff::Error> for Error {
190 fn from(e: jiff::Error) -> Self {
191 Error::Parsing(e.to_string())
192 }
193}
194
195impl From<hex::FromHexError> for Error {
196 fn from(e: hex::FromHexError) -> Self {
197 Error::Parsing(e.to_string())
198 }
199}
200
201impl From<databend_client::Error> for Error {
202 fn from(e: databend_client::Error) -> Self {
203 Error::Api(e)
204 }
205}
206
207impl From<ConvertError> for Error {
208 fn from(e: ConvertError) -> Self {
209 Error::Convert(e)
210 }
211}