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    #[cfg(feature = "flight-sql")]
49    Arrow(arrow_schema::ArrowError),
50    Convert(ConvertError),
51}
52
53impl std::fmt::Display for Error {
54    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55        match self {
56            Error::Parsing(msg) => write!(f, "ParseError: {msg}"),
57            Error::Protocol(msg) => write!(f, "ProtocolError: {msg}"),
58            Error::Transport(msg) => write!(f, "TransportError: {msg}"),
59            Error::IO(msg) => write!(f, "IOError: {msg}"),
60
61            Error::BadArgument(msg) => write!(f, "BadArgument: {msg}"),
62            Error::InvalidResponse(msg) => write!(f, "ResponseError: {msg}"),
63            #[cfg(feature = "flight-sql")]
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                write!(f, "ArrowError: {msg}")
78            }
79            Error::Convert(e) => write!(
80                f,
81                "ConvertError: cannot convert {} to {}: {:?}",
82                e.data, e.target, e.message
83            ),
84            Error::Api(e) => write!(f, "APIError: {e}"),
85        }
86    }
87}
88
89impl std::error::Error for Error {}
90
91pub type Result<T, E = Error> = core::result::Result<T, E>;
92
93impl From<url::ParseError> for Error {
94    fn from(e: url::ParseError) -> Self {
95        Error::Parsing(e.to_string())
96    }
97}
98
99impl From<std::num::ParseIntError> for Error {
100    fn from(e: std::num::ParseIntError) -> Self {
101        Error::Parsing(e.to_string())
102    }
103}
104
105impl From<std::str::ParseBoolError> for Error {
106    fn from(e: std::str::ParseBoolError) -> Self {
107        Error::Parsing(e.to_string())
108    }
109}
110
111impl From<std::num::ParseFloatError> for Error {
112    fn from(e: std::num::ParseFloatError) -> Self {
113        Error::Parsing(e.to_string())
114    }
115}
116
117impl From<chrono::ParseError> for Error {
118    fn from(e: chrono::ParseError) -> Self {
119        Error::Parsing(e.to_string())
120    }
121}
122
123impl From<std::io::Error> for Error {
124    fn from(e: std::io::Error) -> Self {
125        Error::IO(e.to_string())
126    }
127}
128
129impl From<glob::GlobError> for Error {
130    fn from(e: glob::GlobError) -> Self {
131        Error::IO(e.to_string())
132    }
133}
134
135impl From<glob::PatternError> for Error {
136    fn from(e: glob::PatternError) -> Self {
137        Error::Parsing(e.to_string())
138    }
139}
140
141#[cfg(feature = "flight-sql")]
142impl From<tonic::Status> for Error {
143    fn from(e: tonic::Status) -> Self {
144        Error::Protocol(e.to_string())
145    }
146}
147
148#[cfg(feature = "flight-sql")]
149impl From<tonic::transport::Error> for Error {
150    fn from(e: tonic::transport::Error) -> Self {
151        Error::Transport(e.to_string())
152    }
153}
154
155#[cfg(feature = "flight-sql")]
156impl From<arrow_schema::ArrowError> for Error {
157    fn from(e: arrow_schema::ArrowError) -> Self {
158        Error::Arrow(e)
159    }
160}
161
162impl From<std::str::Utf8Error> for Error {
163    fn from(e: std::str::Utf8Error) -> Self {
164        Error::Parsing(e.to_string())
165    }
166}
167
168impl From<std::string::FromUtf8Error> for Error {
169    fn from(e: std::string::FromUtf8Error) -> Self {
170        Error::Parsing(e.to_string())
171    }
172}
173
174impl From<serde_json::Error> for Error {
175    fn from(e: serde_json::Error) -> Self {
176        Error::Parsing(e.to_string())
177    }
178}
179
180impl From<hex::FromHexError> for Error {
181    fn from(e: hex::FromHexError) -> Self {
182        Error::Parsing(e.to_string())
183    }
184}
185
186impl From<databend_client::Error> for Error {
187    fn from(e: databend_client::Error) -> Self {
188        Error::Api(e)
189    }
190}
191
192impl From<ConvertError> for Error {
193    fn from(e: ConvertError) -> Self {
194        Error::Convert(e)
195    }
196}
197
198impl From<GeozeroError> for Error {
199    fn from(e: GeozeroError) -> Self {
200        Error::Parsing(e.to_string())
201    }
202}