databend_driver_core/
error.rs

1// Copyright 2021 Datafuse Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use geozero::error::GeozeroError;
16
17#[derive(Debug)]
18pub struct ConvertError {
19    target: &'static str,
20    data: String,
21    message: Option<String>,
22}
23
24impl ConvertError {
25    pub fn new(target: &'static str, data: String) -> Self {
26        ConvertError {
27            target,
28            data,
29            message: None,
30        }
31    }
32
33    pub fn with_message(mut self, message: String) -> Self {
34        self.message = Some(message);
35        self
36    }
37}
38
39#[derive(Debug)]
40pub enum Error {
41    Parsing(String),
42    Protocol(String),
43    Transport(String),
44    IO(String),
45    BadArgument(String),
46    InvalidResponse(String),
47    Api(databend_client::Error),
48    Arrow(arrow_schema::ArrowError),
49    Convert(ConvertError),
50}
51
52impl std::fmt::Display for Error {
53    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
54        match self {
55            Error::Parsing(msg) => write!(f, "ParseError: {msg}"),
56            Error::Protocol(msg) => write!(f, "ProtocolError: {msg}"),
57            Error::Transport(msg) => write!(f, "TransportError: {msg}"),
58            Error::IO(msg) => write!(f, "IOError: {msg}"),
59
60            Error::BadArgument(msg) => write!(f, "BadArgument: {msg}"),
61            Error::InvalidResponse(msg) => write!(f, "ResponseError: {msg}"),
62            Error::Arrow(e) => {
63                let msg = match e {
64                    arrow_schema::ArrowError::IoError(msg, _) => {
65                        static START: &str = "Code:";
66                        static END: &str = ". at";
67
68                        let message_index = msg.find(START).unwrap_or(0);
69                        let message_end_index = msg.find(END).unwrap_or(msg.len());
70                        let message = &msg[message_index..message_end_index];
71                        message.replace("\\n", "\n")
72                    }
73                    other => format!("{other}"),
74                };
75                write!(f, "ArrowError: {msg}")
76            }
77            Error::Convert(e) => write!(
78                f,
79                "ConvertError: cannot convert {} to {}: {:?}",
80                e.data, e.target, e.message
81            ),
82            Error::Api(e) => write!(f, "APIError: {e}"),
83        }
84    }
85}
86
87impl std::error::Error for Error {}
88
89pub type Result<T, E = Error> = core::result::Result<T, E>;
90
91impl From<url::ParseError> for Error {
92    fn from(e: url::ParseError) -> Self {
93        Error::Parsing(e.to_string())
94    }
95}
96
97impl From<std::num::ParseIntError> for Error {
98    fn from(e: std::num::ParseIntError) -> Self {
99        Error::Parsing(e.to_string())
100    }
101}
102
103impl From<std::str::ParseBoolError> for Error {
104    fn from(e: std::str::ParseBoolError) -> Self {
105        Error::Parsing(e.to_string())
106    }
107}
108
109impl From<std::num::ParseFloatError> for Error {
110    fn from(e: std::num::ParseFloatError) -> Self {
111        Error::Parsing(e.to_string())
112    }
113}
114
115impl From<chrono::ParseError> for Error {
116    fn from(e: chrono::ParseError) -> Self {
117        Error::Parsing(e.to_string())
118    }
119}
120
121impl From<std::io::Error> for Error {
122    fn from(e: std::io::Error) -> Self {
123        Error::IO(e.to_string())
124    }
125}
126
127impl From<glob::GlobError> for Error {
128    fn from(e: glob::GlobError) -> Self {
129        Error::IO(e.to_string())
130    }
131}
132
133impl From<glob::PatternError> for Error {
134    fn from(e: glob::PatternError) -> Self {
135        Error::Parsing(e.to_string())
136    }
137}
138
139#[cfg(feature = "flight-sql")]
140impl From<tonic::Status> for Error {
141    fn from(e: tonic::Status) -> Self {
142        Error::Protocol(e.to_string())
143    }
144}
145
146#[cfg(feature = "flight-sql")]
147impl From<tonic::transport::Error> for Error {
148    fn from(e: tonic::transport::Error) -> Self {
149        Error::Transport(e.to_string())
150    }
151}
152
153impl From<arrow_schema::ArrowError> for Error {
154    fn from(e: arrow_schema::ArrowError) -> Self {
155        Error::Arrow(e)
156    }
157}
158
159impl From<std::str::Utf8Error> for Error {
160    fn from(e: std::str::Utf8Error) -> Self {
161        Error::Parsing(e.to_string())
162    }
163}
164
165impl From<std::string::FromUtf8Error> for Error {
166    fn from(e: std::string::FromUtf8Error) -> Self {
167        Error::Parsing(e.to_string())
168    }
169}
170
171impl From<serde_json::Error> for Error {
172    fn from(e: serde_json::Error) -> Self {
173        Error::Parsing(e.to_string())
174    }
175}
176
177impl From<hex::FromHexError> for Error {
178    fn from(e: hex::FromHexError) -> Self {
179        Error::Parsing(e.to_string())
180    }
181}
182
183impl From<databend_client::Error> for Error {
184    fn from(e: databend_client::Error) -> Self {
185        Error::Api(e)
186    }
187}
188
189impl From<ConvertError> for Error {
190    fn from(e: ConvertError) -> Self {
191        Error::Convert(e)
192    }
193}
194
195impl From<GeozeroError> for Error {
196    fn from(e: GeozeroError) -> Self {
197        Error::Parsing(e.to_string())
198    }
199}