1use std::any::Any;
16use std::sync::Arc;
17
18use common_error::define_into_tonic_status;
19use common_error::ext::{BoxedError, ErrorExt};
20use common_error::status_code::StatusCode;
21use common_macro::stack_trace_debug;
22use snafu::{Location, Snafu};
23use store_api::storage::RegionId;
24use table::error::Error as TableError;
25use tokio::time::error::Elapsed;
26
27#[derive(Snafu)]
29#[snafu(visibility(pub))]
30#[stack_trace_debug]
31pub enum Error {
32 #[snafu(display("Failed to execute async task"))]
33 AsyncTaskExecute {
34 #[snafu(implicit)]
35 location: Location,
36 source: Arc<Error>,
37 },
38
39 #[snafu(display("Failed to watch change"))]
40 WatchAsyncTaskChange {
41 #[snafu(implicit)]
42 location: Location,
43 #[snafu(source)]
44 error: tokio::sync::watch::error::RecvError,
45 },
46
47 #[snafu(display("Failed to handle heartbeat response"))]
48 HandleHeartbeatResponse {
49 #[snafu(implicit)]
50 location: Location,
51 source: common_meta::error::Error,
52 },
53
54 #[snafu(display("Failed to get info from meta server"))]
55 GetMetadata {
56 #[snafu(implicit)]
57 location: Location,
58 source: common_meta::error::Error,
59 },
60
61 #[snafu(display("Failed to execute logical plan"))]
62 ExecuteLogicalPlan {
63 #[snafu(implicit)]
64 location: Location,
65 source: query::error::Error,
66 },
67
68 #[snafu(display("Failed to create plan decoder"))]
69 NewPlanDecoder {
70 #[snafu(implicit)]
71 location: Location,
72 source: query::error::Error,
73 },
74
75 #[snafu(display("Failed to decode logical plan"))]
76 DecodeLogicalPlan {
77 #[snafu(implicit)]
78 location: Location,
79 source: common_query::error::Error,
80 },
81
82 #[snafu(display("Schema not found: {}", name))]
83 SchemaNotFound {
84 name: String,
85 #[snafu(implicit)]
86 location: Location,
87 },
88
89 #[snafu(display("Missing timestamp column in request"))]
90 MissingTimestampColumn {
91 #[snafu(implicit)]
92 location: Location,
93 },
94
95 #[snafu(display("Failed to delete value from table: {}", table_name))]
96 Delete {
97 table_name: String,
98 #[snafu(implicit)]
99 location: Location,
100 source: TableError,
101 },
102
103 #[snafu(display("Failed to start server"))]
104 StartServer {
105 #[snafu(implicit)]
106 location: Location,
107 source: servers::error::Error,
108 },
109
110 #[snafu(display("Failed to parse address {}", addr))]
111 ParseAddr {
112 addr: String,
113 #[snafu(source)]
114 error: std::net::AddrParseError,
115 },
116
117 #[snafu(display("Failed to create directory {}", dir))]
118 CreateDir {
119 dir: String,
120 #[snafu(source)]
121 error: std::io::Error,
122 },
123
124 #[snafu(display("Failed to remove directory {}", dir))]
125 RemoveDir {
126 dir: String,
127 #[snafu(source)]
128 error: std::io::Error,
129 },
130
131 #[snafu(display("Failed to open log store"))]
132 OpenLogStore {
133 #[snafu(implicit)]
134 location: Location,
135 source: Box<log_store::error::Error>,
136 },
137
138 #[snafu(display("Invalid SQL, error: {}", msg))]
139 InvalidSql { msg: String },
140
141 #[snafu(display("Illegal primary keys definition: {}", msg))]
142 IllegalPrimaryKeysDef {
143 msg: String,
144 #[snafu(implicit)]
145 location: Location,
146 },
147
148 #[snafu(display("Schema {} already exists", name))]
149 SchemaExists {
150 name: String,
151 #[snafu(implicit)]
152 location: Location,
153 },
154
155 #[snafu(display("Failed to initialize meta client"))]
156 MetaClientInit {
157 #[snafu(implicit)]
158 location: Location,
159 source: meta_client::error::Error,
160 },
161
162 #[snafu(display("Missing node id in Datanode config"))]
163 MissingNodeId {
164 #[snafu(implicit)]
165 location: Location,
166 },
167
168 #[snafu(display("Failed to build datanode"))]
169 BuildDatanode {
170 #[snafu(implicit)]
171 location: Location,
172 source: BoxedError,
173 },
174
175 #[snafu(display("Failed to build http client"))]
176 BuildHttpClient {
177 #[snafu(implicit)]
178 location: Location,
179 #[snafu(source)]
180 error: reqwest::Error,
181 },
182
183 #[snafu(display("Missing required field: {}", name))]
184 MissingRequiredField {
185 name: String,
186 #[snafu(implicit)]
187 location: Location,
188 },
189
190 #[snafu(display(
191 "No valid default value can be built automatically, column: {}",
192 column,
193 ))]
194 ColumnNoneDefaultValue {
195 column: String,
196 #[snafu(implicit)]
197 location: Location,
198 },
199
200 #[snafu(display("Failed to shutdown server"))]
201 ShutdownServer {
202 #[snafu(implicit)]
203 location: Location,
204 source: servers::error::Error,
205 },
206
207 #[snafu(display("Failed to shutdown instance"))]
208 ShutdownInstance {
209 #[snafu(implicit)]
210 location: Location,
211 source: BoxedError,
212 },
213
214 #[snafu(display("Payload not exist"))]
215 PayloadNotExist {
216 #[snafu(implicit)]
217 location: Location,
218 },
219
220 #[snafu(display("Unexpected, violated: {}", violated))]
221 Unexpected {
222 violated: String,
223 #[snafu(implicit)]
224 location: Location,
225 },
226
227 #[snafu(display("Failed to handle request for region {}", region_id))]
228 HandleRegionRequest {
229 region_id: RegionId,
230 #[snafu(implicit)]
231 location: Location,
232 source: BoxedError,
233 },
234
235 #[snafu(display("Failed to open batch regions"))]
236 HandleBatchOpenRequest {
237 #[snafu(implicit)]
238 location: Location,
239 source: BoxedError,
240 },
241
242 #[snafu(display("Failed to handle batch ddl request, ddl_type: {}", ddl_type))]
243 HandleBatchDdlRequest {
244 #[snafu(implicit)]
245 location: Location,
246 source: BoxedError,
247 ddl_type: String,
248 },
249
250 #[snafu(display("RegionId {} not found", region_id))]
251 RegionNotFound {
252 region_id: RegionId,
253 #[snafu(implicit)]
254 location: Location,
255 },
256
257 #[snafu(display("Region {} not ready", region_id))]
258 RegionNotReady {
259 region_id: RegionId,
260 #[snafu(implicit)]
261 location: Location,
262 },
263
264 #[snafu(display("Region {} is busy", region_id))]
265 RegionBusy {
266 region_id: RegionId,
267 #[snafu(implicit)]
268 location: Location,
269 },
270
271 #[snafu(display("Region engine {} is not registered", name))]
272 RegionEngineNotFound {
273 name: String,
274 #[snafu(implicit)]
275 location: Location,
276 },
277
278 #[snafu(display("Unsupported output type, expected: {}", expected))]
279 UnsupportedOutput {
280 expected: String,
281 #[snafu(implicit)]
282 location: Location,
283 },
284
285 #[snafu(display("Failed to build region requests"))]
286 BuildRegionRequests {
287 #[snafu(implicit)]
288 location: Location,
289 source: store_api::metadata::MetadataError,
290 },
291
292 #[snafu(display("Failed to stop region engine {}", name))]
293 StopRegionEngine {
294 name: String,
295 #[snafu(implicit)]
296 location: Location,
297 source: BoxedError,
298 },
299
300 #[snafu(display(
301 "Failed to find logical regions in physical region {}",
302 physical_region_id
303 ))]
304 FindLogicalRegions {
305 physical_region_id: RegionId,
306 source: metric_engine::error::Error,
307 #[snafu(implicit)]
308 location: Location,
309 },
310
311 #[snafu(display("Failed to build mito engine"))]
312 BuildMitoEngine {
313 source: mito2::error::Error,
314 #[snafu(implicit)]
315 location: Location,
316 },
317
318 #[snafu(display("Failed to build metric engine"))]
319 BuildMetricEngine {
320 source: metric_engine::error::Error,
321 #[snafu(implicit)]
322 location: Location,
323 },
324
325 #[snafu(display("Failed to run gc for region {}", region_id))]
326 GcMitoEngine {
327 region_id: RegionId,
328 source: mito2::error::Error,
329 #[snafu(implicit)]
330 location: Location,
331 },
332
333 #[snafu(display("Invalid arguments for GC: {}", msg))]
334 InvalidGcArgs {
335 msg: String,
336 #[snafu(implicit)]
337 location: Location,
338 },
339
340 #[snafu(display("Failed to list SST entries from storage"))]
341 ListStorageSsts {
342 #[snafu(implicit)]
343 location: Location,
344 source: mito2::error::Error,
345 },
346
347 #[snafu(display("Failed to serialize options to TOML"))]
348 TomlFormat {
349 #[snafu(implicit)]
350 location: Location,
351 #[snafu(source(from(common_config::error::Error, Box::new)))]
352 source: Box<common_config::error::Error>,
353 },
354
355 #[snafu(display(
356 "Failed to get region metadata from engine {} for region_id {}",
357 engine,
358 region_id,
359 ))]
360 GetRegionMetadata {
361 engine: String,
362 region_id: RegionId,
363 #[snafu(implicit)]
364 location: Location,
365 source: BoxedError,
366 },
367
368 #[snafu(display("DataFusion"))]
369 DataFusion {
370 #[snafu(source)]
371 error: datafusion::error::DataFusionError,
372 #[snafu(implicit)]
373 location: Location,
374 },
375
376 #[snafu(display("Failed to acquire permit, source closed"))]
377 ConcurrentQueryLimiterClosed {
378 #[snafu(source)]
379 error: tokio::sync::AcquireError,
380 #[snafu(implicit)]
381 location: Location,
382 },
383
384 #[snafu(display("Failed to acquire permit under timeouts"))]
385 ConcurrentQueryLimiterTimeout {
386 #[snafu(source)]
387 error: Elapsed,
388 #[snafu(implicit)]
389 location: Location,
390 },
391
392 #[snafu(display("Cache not found in registry"))]
393 MissingCache {
394 #[snafu(implicit)]
395 location: Location,
396 },
397
398 #[snafu(display("Failed to serialize json"))]
399 SerializeJson {
400 #[snafu(source)]
401 error: serde_json::Error,
402 #[snafu(implicit)]
403 location: Location,
404 },
405
406 #[snafu(display("Failed object store operation"))]
407 ObjectStore {
408 source: object_store::error::Error,
409 #[snafu(implicit)]
410 location: Location,
411 },
412
413 #[snafu(display("Failed to build cache store"))]
414 BuildCacheStore {
415 #[snafu(source)]
416 error: object_store::Error,
417 #[snafu(implicit)]
418 location: Location,
419 },
420
421 #[snafu(display("Not yet implemented: {what}"))]
422 NotYetImplemented { what: String },
423}
424
425pub type Result<T> = std::result::Result<T, Error>;
426
427impl ErrorExt for Error {
428 fn status_code(&self) -> StatusCode {
429 use Error::*;
430 match self {
431 NewPlanDecoder { source, .. } | ExecuteLogicalPlan { source, .. } => {
432 source.status_code()
433 }
434
435 BuildRegionRequests { source, .. } => source.status_code(),
436 HandleHeartbeatResponse { source, .. } | GetMetadata { source, .. } => {
437 source.status_code()
438 }
439
440 DecodeLogicalPlan { source, .. } => source.status_code(),
441
442 Delete { source, .. } => source.status_code(),
443
444 InvalidSql { .. }
445 | IllegalPrimaryKeysDef { .. }
446 | MissingTimestampColumn { .. }
447 | SchemaNotFound { .. }
448 | SchemaExists { .. }
449 | MissingNodeId { .. }
450 | ColumnNoneDefaultValue { .. }
451 | MissingRequiredField { .. }
452 | RegionEngineNotFound { .. }
453 | ParseAddr { .. }
454 | TomlFormat { .. }
455 | BuildDatanode { .. } => StatusCode::InvalidArguments,
456
457 PayloadNotExist { .. }
458 | Unexpected { .. }
459 | WatchAsyncTaskChange { .. }
460 | BuildHttpClient { .. } => StatusCode::Unexpected,
461
462 AsyncTaskExecute { source, .. } => source.status_code(),
463
464 CreateDir { .. }
465 | RemoveDir { .. }
466 | ShutdownInstance { .. }
467 | DataFusion { .. }
468 | InvalidGcArgs { .. } => StatusCode::Internal,
469
470 RegionNotFound { .. } => StatusCode::RegionNotFound,
471 RegionNotReady { .. } => StatusCode::RegionNotReady,
472 RegionBusy { .. } => StatusCode::RegionBusy,
473
474 StartServer { source, .. } | ShutdownServer { source, .. } => source.status_code(),
475
476 OpenLogStore { source, .. } => source.status_code(),
477 MetaClientInit { source, .. } => source.status_code(),
478 UnsupportedOutput { .. } | NotYetImplemented { .. } => StatusCode::Unsupported,
479 HandleRegionRequest { source, .. }
480 | GetRegionMetadata { source, .. }
481 | HandleBatchOpenRequest { source, .. }
482 | HandleBatchDdlRequest { source, .. } => source.status_code(),
483 StopRegionEngine { source, .. } => source.status_code(),
484
485 FindLogicalRegions { source, .. } => source.status_code(),
486 BuildMitoEngine { source, .. } | GcMitoEngine { source, .. } => source.status_code(),
487 BuildMetricEngine { source, .. } => source.status_code(),
488 ListStorageSsts { source, .. } => source.status_code(),
489 ConcurrentQueryLimiterClosed { .. } | ConcurrentQueryLimiterTimeout { .. } => {
490 StatusCode::RegionBusy
491 }
492 MissingCache { .. } => StatusCode::Internal,
493 SerializeJson { .. } => StatusCode::Internal,
494
495 ObjectStore { source, .. } => source.status_code(),
496 BuildCacheStore { .. } => StatusCode::StorageUnavailable,
497 }
498 }
499
500 fn as_any(&self) -> &dyn Any {
501 self
502 }
503}
504
505define_into_tonic_status!(Error);