1use std::any::Any;
16
17use common_error::ext::{BoxedError, ErrorExt};
18use common_error::status_code::StatusCode;
19use common_macro::stack_trace_debug;
20use common_meta::peer::Peer;
21use object_store::Error as ObjectStoreError;
22use snafu::{Location, Snafu};
23use store_api::storage::TableId;
24
25#[derive(Snafu)]
26#[snafu(visibility(pub))]
27#[stack_trace_debug]
28pub enum Error {
29 #[snafu(display("Failed to install ring crypto provider: {}", msg))]
30 InitTlsProvider {
31 #[snafu(implicit)]
32 location: Location,
33 msg: String,
34 },
35
36 #[snafu(display("Failed to create default catalog and schema"))]
37 InitMetadata {
38 #[snafu(implicit)]
39 location: Location,
40 source: common_meta::error::Error,
41 },
42
43 #[snafu(display("Failed to init DDL manager"))]
44 InitDdlManager {
45 #[snafu(implicit)]
46 location: Location,
47 source: common_meta::error::Error,
48 },
49
50 #[snafu(display("Failed to init default timezone"))]
51 InitTimezone {
52 #[snafu(implicit)]
53 location: Location,
54 source: common_time::error::Error,
55 },
56
57 #[snafu(display("Failed to start procedure manager"))]
58 StartProcedureManager {
59 #[snafu(implicit)]
60 location: Location,
61 source: common_procedure::error::Error,
62 },
63
64 #[snafu(display("Failed to stop procedure manager"))]
65 StopProcedureManager {
66 #[snafu(implicit)]
67 location: Location,
68 source: common_procedure::error::Error,
69 },
70
71 #[snafu(display("Failed to start wal options allocator"))]
72 StartWalOptionsAllocator {
73 #[snafu(implicit)]
74 location: Location,
75 source: common_meta::error::Error,
76 },
77
78 #[snafu(display("Failed to get table metadata"))]
79 TableMetadata {
80 #[snafu(implicit)]
81 location: Location,
82 source: common_meta::error::Error,
83 },
84
85 #[snafu(display("Unexpected error: {}", msg))]
86 Unexpected {
87 msg: String,
88 #[snafu(implicit)]
89 location: Location,
90 },
91
92 #[snafu(display("Missing config, msg: {}", msg))]
93 MissingConfig {
94 msg: String,
95 #[snafu(implicit)]
96 location: Location,
97 },
98
99 #[snafu(display("Illegal config: {}", msg))]
100 IllegalConfig {
101 msg: String,
102 #[snafu(implicit)]
103 location: Location,
104 },
105
106 #[snafu(display("Failed to parse proxy options: {}", error))]
107 ParseProxyOpts {
108 #[snafu(source)]
109 error: reqwest::Error,
110 #[snafu(implicit)]
111 location: Location,
112 },
113
114 #[snafu(display("Failed to build reqwest client: {}", error))]
115 BuildClient {
116 #[snafu(implicit)]
117 location: Location,
118 #[snafu(source)]
119 error: reqwest::Error,
120 },
121
122 #[snafu(display("Failed to parse SQL: {}", sql))]
123 ParseSql {
124 sql: String,
125 #[snafu(implicit)]
126 location: Location,
127 source: query::error::Error,
128 },
129
130 #[snafu(display("Failed to plan statement"))]
131 PlanStatement {
132 #[snafu(implicit)]
133 location: Location,
134 source: query::error::Error,
135 },
136
137 #[snafu(display("Failed to load layered config"))]
138 LoadLayeredConfig {
139 #[snafu(source(from(common_config::error::Error, Box::new)))]
140 source: Box<common_config::error::Error>,
141 #[snafu(implicit)]
142 location: Location,
143 },
144
145 #[snafu(display("Failed to connect to Etcd at {etcd_addr}"))]
146 ConnectEtcd {
147 etcd_addr: String,
148 #[snafu(source)]
149 error: etcd_client::Error,
150 #[snafu(implicit)]
151 location: Location,
152 },
153
154 #[snafu(display("Failed to serde json"))]
155 SerdeJson {
156 #[snafu(source)]
157 error: serde_json::error::Error,
158 #[snafu(implicit)]
159 location: Location,
160 },
161
162 #[snafu(display("Failed to run http request: {reason}"))]
163 HttpQuerySql {
164 reason: String,
165 #[snafu(source)]
166 error: reqwest::Error,
167 #[snafu(implicit)]
168 location: Location,
169 },
170
171 #[snafu(display("Empty result from output"))]
172 EmptyResult {
173 #[snafu(implicit)]
174 location: Location,
175 },
176
177 #[snafu(display("Failed to manipulate file"))]
178 FileIo {
179 #[snafu(implicit)]
180 location: Location,
181 #[snafu(source)]
182 error: std::io::Error,
183 },
184
185 #[snafu(display("Failed to create directory {}", dir))]
186 CreateDir {
187 dir: String,
188 #[snafu(source)]
189 error: std::io::Error,
190 },
191
192 #[snafu(display("Failed to spawn thread"))]
193 SpawnThread {
194 #[snafu(source)]
195 error: std::io::Error,
196 },
197
198 #[snafu(display("Other error"))]
199 Other {
200 source: BoxedError,
201 #[snafu(implicit)]
202 location: Location,
203 },
204
205 #[snafu(display("Failed to build runtime"))]
206 BuildRuntime {
207 #[snafu(implicit)]
208 location: Location,
209 source: common_runtime::error::Error,
210 },
211
212 #[snafu(display("Failed to get cache from cache registry: {}", name))]
213 CacheRequired {
214 #[snafu(implicit)]
215 location: Location,
216 name: String,
217 },
218
219 #[snafu(display("Failed to build cache registry"))]
220 BuildCacheRegistry {
221 #[snafu(implicit)]
222 location: Location,
223 source: cache::error::Error,
224 },
225
226 #[snafu(display("Failed to initialize meta client"))]
227 MetaClientInit {
228 #[snafu(implicit)]
229 location: Location,
230 source: meta_client::error::Error,
231 },
232
233 #[snafu(display("Cannot find schema {schema} in catalog {catalog}"))]
234 SchemaNotFound {
235 catalog: String,
236 schema: String,
237 #[snafu(implicit)]
238 location: Location,
239 },
240
241 #[snafu(display("Table not found: {table_id}"))]
242 TableNotFound {
243 table_id: TableId,
244 #[snafu(implicit)]
245 location: Location,
246 },
247
248 #[snafu(display("OpenDAL operator failed"))]
249 OpenDal {
250 #[snafu(implicit)]
251 location: Location,
252 #[snafu(source)]
253 error: ObjectStoreError,
254 },
255
256 #[snafu(display("Output directory not set"))]
257 OutputDirNotSet {
258 #[snafu(implicit)]
259 location: Location,
260 },
261
262 #[snafu(display("Empty store addresses"))]
263 EmptyStoreAddrs {
264 #[snafu(implicit)]
265 location: Location,
266 },
267
268 #[snafu(display("Unsupported memory backend"))]
269 UnsupportedMemoryBackend {
270 #[snafu(implicit)]
271 location: Location,
272 },
273
274 #[snafu(display("File path invalid: {}", msg))]
275 InvalidFilePath {
276 msg: String,
277 #[snafu(implicit)]
278 location: Location,
279 },
280
281 #[snafu(display("Invalid arguments: {}", msg))]
282 InvalidArguments {
283 msg: String,
284 #[snafu(implicit)]
285 location: Location,
286 },
287
288 #[snafu(display("Failed to init backend"))]
289 InitBackend {
290 #[snafu(implicit)]
291 location: Location,
292 #[snafu(source)]
293 error: ObjectStoreError,
294 },
295
296 #[snafu(display("Covert column schemas to defs failed"))]
297 CovertColumnSchemasToDefs {
298 #[snafu(implicit)]
299 location: Location,
300 source: operator::error::Error,
301 },
302
303 #[snafu(display("Failed to send request to datanode: {}", peer))]
304 SendRequestToDatanode {
305 peer: Peer,
306 #[snafu(implicit)]
307 location: Location,
308 source: common_meta::error::Error,
309 },
310
311 #[snafu(display("Failed to get current directory"))]
312 GetCurrentDir {
313 #[snafu(implicit)]
314 location: Location,
315 #[snafu(source)]
316 error: std::io::Error,
317 },
318}
319
320pub type Result<T> = std::result::Result<T, Error>;
321
322impl ErrorExt for Error {
323 fn status_code(&self) -> StatusCode {
324 match self {
325 Error::InitMetadata { source, .. }
326 | Error::InitDdlManager { source, .. }
327 | Error::TableMetadata { source, .. } => source.status_code(),
328
329 Error::MissingConfig { .. }
330 | Error::LoadLayeredConfig { .. }
331 | Error::IllegalConfig { .. }
332 | Error::InitTimezone { .. }
333 | Error::ConnectEtcd { .. }
334 | Error::CreateDir { .. }
335 | Error::EmptyResult { .. }
336 | Error::InvalidFilePath { .. }
337 | Error::UnsupportedMemoryBackend { .. }
338 | Error::InvalidArguments { .. }
339 | Error::ParseProxyOpts { .. } => StatusCode::InvalidArguments,
340
341 Error::CovertColumnSchemasToDefs { source, .. } => source.status_code(),
342 Error::SendRequestToDatanode { source, .. } => source.status_code(),
343
344 Error::StartProcedureManager { source, .. }
345 | Error::StopProcedureManager { source, .. } => source.status_code(),
346 Error::StartWalOptionsAllocator { source, .. } => source.status_code(),
347 Error::HttpQuerySql { .. } => StatusCode::Internal,
348 Error::ParseSql { source, .. } | Error::PlanStatement { source, .. } => {
349 source.status_code()
350 }
351 Error::Unexpected { .. } => StatusCode::Unexpected,
352
353 Error::SerdeJson { .. }
354 | Error::FileIo { .. }
355 | Error::SpawnThread { .. }
356 | Error::InitTlsProvider { .. }
357 | Error::BuildClient { .. } => StatusCode::Unexpected,
358
359 Error::Other { source, .. } => source.status_code(),
360 Error::OpenDal { .. } | Error::InitBackend { .. } => StatusCode::Internal,
361 Error::OutputDirNotSet { .. } | Error::EmptyStoreAddrs { .. } => {
362 StatusCode::InvalidArguments
363 }
364
365 Error::BuildRuntime { source, .. } => source.status_code(),
366
367 Error::CacheRequired { .. }
368 | Error::BuildCacheRegistry { .. }
369 | Error::GetCurrentDir { .. } => StatusCode::Internal,
370 Error::MetaClientInit { source, .. } => source.status_code(),
371 Error::TableNotFound { .. } => StatusCode::TableNotFound,
372 Error::SchemaNotFound { .. } => StatusCode::DatabaseNotFound,
373 }
374 }
375
376 fn as_any(&self) -> &dyn Any {
377 self
378 }
379}