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::{RegionId, 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 provider"))]
72 StartWalProvider {
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("Failed to build create region request for region: {region_id}"))]
86 BuildCreateRegionRequest {
87 region_id: RegionId,
88 #[snafu(implicit)]
89 location: Location,
90 source: common_meta::error::Error,
91 },
92
93 #[snafu(display("Unexpected error: {}", msg))]
94 Unexpected {
95 msg: String,
96 #[snafu(implicit)]
97 location: Location,
98 },
99
100 #[snafu(display("Missing config, msg: {}", msg))]
101 MissingConfig {
102 msg: String,
103 #[snafu(implicit)]
104 location: Location,
105 },
106
107 #[snafu(display("Illegal config: {}", msg))]
108 IllegalConfig {
109 msg: String,
110 #[snafu(implicit)]
111 location: Location,
112 },
113
114 #[snafu(display("Failed to parse proxy options: {}", error))]
115 ParseProxyOpts {
116 #[snafu(source)]
117 error: reqwest::Error,
118 #[snafu(implicit)]
119 location: Location,
120 },
121
122 #[snafu(display("Failed to build reqwest client: {}", error))]
123 BuildClient {
124 #[snafu(implicit)]
125 location: Location,
126 #[snafu(source)]
127 error: reqwest::Error,
128 },
129
130 #[snafu(display("Failed to parse SQL: {}", sql))]
131 ParseSql {
132 sql: String,
133 #[snafu(implicit)]
134 location: Location,
135 source: query::error::Error,
136 },
137
138 #[snafu(display("Failed to plan statement"))]
139 PlanStatement {
140 #[snafu(implicit)]
141 location: Location,
142 source: query::error::Error,
143 },
144
145 #[snafu(display("Failed to load layered config"))]
146 LoadLayeredConfig {
147 #[snafu(source(from(common_config::error::Error, Box::new)))]
148 source: Box<common_config::error::Error>,
149 #[snafu(implicit)]
150 location: Location,
151 },
152
153 #[snafu(display("Failed to connect to Etcd at {etcd_addr}"))]
154 ConnectEtcd {
155 etcd_addr: String,
156 #[snafu(source)]
157 error: etcd_client::Error,
158 #[snafu(implicit)]
159 location: Location,
160 },
161
162 #[snafu(display("Failed to serde json"))]
163 SerdeJson {
164 #[snafu(source)]
165 error: serde_json::error::Error,
166 #[snafu(implicit)]
167 location: Location,
168 },
169
170 #[snafu(display("Failed to run http request: {reason}"))]
171 HttpQuerySql {
172 reason: String,
173 #[snafu(source)]
174 error: reqwest::Error,
175 #[snafu(implicit)]
176 location: Location,
177 },
178
179 #[snafu(display("Empty result from output"))]
180 EmptyResult {
181 #[snafu(implicit)]
182 location: Location,
183 },
184
185 #[snafu(display("Failed to manipulate file"))]
186 FileIo {
187 #[snafu(implicit)]
188 location: Location,
189 #[snafu(source)]
190 error: std::io::Error,
191 },
192
193 #[snafu(display("Failed to create directory {}", dir))]
194 CreateDir {
195 dir: String,
196 #[snafu(source)]
197 error: std::io::Error,
198 },
199
200 #[snafu(display("Failed to spawn thread"))]
201 SpawnThread {
202 #[snafu(source)]
203 error: std::io::Error,
204 },
205
206 #[snafu(display("Other error"))]
207 Other {
208 source: BoxedError,
209 #[snafu(implicit)]
210 location: Location,
211 },
212
213 #[snafu(display("Failed to build runtime"))]
214 BuildRuntime {
215 #[snafu(implicit)]
216 location: Location,
217 source: common_runtime::error::Error,
218 },
219
220 #[snafu(display("Failed to get cache from cache registry: {}", name))]
221 CacheRequired {
222 #[snafu(implicit)]
223 location: Location,
224 name: String,
225 },
226
227 #[snafu(display("Failed to build cache registry"))]
228 BuildCacheRegistry {
229 #[snafu(implicit)]
230 location: Location,
231 source: cache::error::Error,
232 },
233
234 #[snafu(display("Failed to initialize meta client"))]
235 MetaClientInit {
236 #[snafu(implicit)]
237 location: Location,
238 source: meta_client::error::Error,
239 },
240
241 #[snafu(display("Cannot find schema {schema} in catalog {catalog}"))]
242 SchemaNotFound {
243 catalog: String,
244 schema: String,
245 #[snafu(implicit)]
246 location: Location,
247 },
248
249 #[snafu(display("Table not found: {table_id}"))]
250 TableNotFound {
251 table_id: TableId,
252 #[snafu(implicit)]
253 location: Location,
254 },
255
256 #[snafu(display("OpenDAL operator failed"))]
257 OpenDal {
258 #[snafu(implicit)]
259 location: Location,
260 #[snafu(source)]
261 error: ObjectStoreError,
262 },
263
264 #[snafu(display("Output directory not set"))]
265 OutputDirNotSet {
266 #[snafu(implicit)]
267 location: Location,
268 },
269
270 #[snafu(display("Empty store addresses"))]
271 EmptyStoreAddrs {
272 #[snafu(implicit)]
273 location: Location,
274 },
275
276 #[snafu(display("Unsupported memory backend"))]
277 UnsupportedMemoryBackend {
278 #[snafu(implicit)]
279 location: Location,
280 },
281
282 #[snafu(display("File path invalid: {}", msg))]
283 InvalidFilePath {
284 msg: String,
285 #[snafu(implicit)]
286 location: Location,
287 },
288
289 #[snafu(display("Invalid arguments: {}", msg))]
290 InvalidArguments {
291 msg: String,
292 #[snafu(implicit)]
293 location: Location,
294 },
295
296 #[snafu(display("Failed to init backend"))]
297 InitBackend {
298 #[snafu(implicit)]
299 location: Location,
300 #[snafu(source)]
301 error: ObjectStoreError,
302 },
303
304 #[snafu(display("Covert column schemas to defs failed"))]
305 CovertColumnSchemasToDefs {
306 #[snafu(implicit)]
307 location: Location,
308 source: operator::error::Error,
309 },
310
311 #[snafu(display("Failed to send request to datanode: {}", peer))]
312 SendRequestToDatanode {
313 peer: Peer,
314 #[snafu(implicit)]
315 location: Location,
316 source: common_meta::error::Error,
317 },
318
319 #[snafu(display("Failed to get current directory"))]
320 GetCurrentDir {
321 #[snafu(implicit)]
322 location: Location,
323 #[snafu(source)]
324 error: std::io::Error,
325 },
326}
327
328pub type Result<T> = std::result::Result<T, Error>;
329
330impl ErrorExt for Error {
331 fn status_code(&self) -> StatusCode {
332 match self {
333 Error::InitMetadata { source, .. }
334 | Error::InitDdlManager { source, .. }
335 | Error::TableMetadata { source, .. }
336 | Error::BuildCreateRegionRequest { source, .. } => source.status_code(),
337
338 Error::MissingConfig { .. }
339 | Error::LoadLayeredConfig { .. }
340 | Error::IllegalConfig { .. }
341 | Error::InitTimezone { .. }
342 | Error::ConnectEtcd { .. }
343 | Error::CreateDir { .. }
344 | Error::EmptyResult { .. }
345 | Error::InvalidFilePath { .. }
346 | Error::UnsupportedMemoryBackend { .. }
347 | Error::InvalidArguments { .. }
348 | Error::ParseProxyOpts { .. } => StatusCode::InvalidArguments,
349
350 Error::CovertColumnSchemasToDefs { source, .. } => source.status_code(),
351 Error::SendRequestToDatanode { source, .. } => source.status_code(),
352
353 Error::StartProcedureManager { source, .. }
354 | Error::StopProcedureManager { source, .. } => source.status_code(),
355 Error::StartWalProvider { source, .. } => source.status_code(),
356 Error::HttpQuerySql { .. } => StatusCode::Internal,
357 Error::ParseSql { source, .. } | Error::PlanStatement { source, .. } => {
358 source.status_code()
359 }
360 Error::Unexpected { .. } => StatusCode::Unexpected,
361
362 Error::SerdeJson { .. }
363 | Error::FileIo { .. }
364 | Error::SpawnThread { .. }
365 | Error::InitTlsProvider { .. }
366 | Error::BuildClient { .. } => StatusCode::Unexpected,
367
368 Error::Other { source, .. } => source.status_code(),
369 Error::OpenDal { .. } | Error::InitBackend { .. } => StatusCode::Internal,
370 Error::OutputDirNotSet { .. } | Error::EmptyStoreAddrs { .. } => {
371 StatusCode::InvalidArguments
372 }
373
374 Error::BuildRuntime { source, .. } => source.status_code(),
375
376 Error::CacheRequired { .. }
377 | Error::BuildCacheRegistry { .. }
378 | Error::GetCurrentDir { .. } => StatusCode::Internal,
379 Error::MetaClientInit { source, .. } => source.status_code(),
380 Error::TableNotFound { .. } => StatusCode::TableNotFound,
381 Error::SchemaNotFound { .. } => StatusCode::DatabaseNotFound,
382 }
383 }
384
385 fn as_any(&self) -> &dyn Any {
386 self
387 }
388}