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 http client"))]
169 BuildHttpClient {
170 #[snafu(implicit)]
171 location: Location,
172 #[snafu(source)]
173 error: reqwest::Error,
174 },
175
176 #[snafu(display("Missing required field: {}", name))]
177 MissingRequiredField {
178 name: String,
179 #[snafu(implicit)]
180 location: Location,
181 },
182
183 #[snafu(display(
184 "No valid default value can be built automatically, column: {}",
185 column,
186 ))]
187 ColumnNoneDefaultValue {
188 column: String,
189 #[snafu(implicit)]
190 location: Location,
191 },
192
193 #[snafu(display("Failed to shutdown server"))]
194 ShutdownServer {
195 #[snafu(implicit)]
196 location: Location,
197 source: servers::error::Error,
198 },
199
200 #[snafu(display("Failed to shutdown instance"))]
201 ShutdownInstance {
202 #[snafu(implicit)]
203 location: Location,
204 source: BoxedError,
205 },
206
207 #[snafu(display("Payload not exist"))]
208 PayloadNotExist {
209 #[snafu(implicit)]
210 location: Location,
211 },
212
213 #[snafu(display("Unexpected, violated: {}", violated))]
214 Unexpected {
215 violated: String,
216 #[snafu(implicit)]
217 location: Location,
218 },
219
220 #[snafu(display("Failed to handle request for region {}", region_id))]
221 HandleRegionRequest {
222 region_id: RegionId,
223 #[snafu(implicit)]
224 location: Location,
225 source: BoxedError,
226 },
227
228 #[snafu(display("Failed to open batch regions"))]
229 HandleBatchOpenRequest {
230 #[snafu(implicit)]
231 location: Location,
232 source: BoxedError,
233 },
234
235 #[snafu(display("Failed to handle batch ddl request, ddl_type: {}", ddl_type))]
236 HandleBatchDdlRequest {
237 #[snafu(implicit)]
238 location: Location,
239 source: BoxedError,
240 ddl_type: String,
241 },
242
243 #[snafu(display("RegionId {} not found", region_id))]
244 RegionNotFound {
245 region_id: RegionId,
246 #[snafu(implicit)]
247 location: Location,
248 },
249
250 #[snafu(display("Region {} not ready", region_id))]
251 RegionNotReady {
252 region_id: RegionId,
253 #[snafu(implicit)]
254 location: Location,
255 },
256
257 #[snafu(display("Region {} is busy", region_id))]
258 RegionBusy {
259 region_id: RegionId,
260 #[snafu(implicit)]
261 location: Location,
262 },
263
264 #[snafu(display("Region engine {} is not registered", name))]
265 RegionEngineNotFound {
266 name: String,
267 #[snafu(implicit)]
268 location: Location,
269 },
270
271 #[snafu(display("Unsupported output type, expected: {}", expected))]
272 UnsupportedOutput {
273 expected: String,
274 #[snafu(implicit)]
275 location: Location,
276 },
277
278 #[snafu(display("Failed to build region requests"))]
279 BuildRegionRequests {
280 #[snafu(implicit)]
281 location: Location,
282 source: store_api::metadata::MetadataError,
283 },
284
285 #[snafu(display("Failed to stop region engine {}", name))]
286 StopRegionEngine {
287 name: String,
288 #[snafu(implicit)]
289 location: Location,
290 source: BoxedError,
291 },
292
293 #[snafu(display(
294 "Failed to find logical regions in physical region {}",
295 physical_region_id
296 ))]
297 FindLogicalRegions {
298 physical_region_id: RegionId,
299 source: metric_engine::error::Error,
300 #[snafu(implicit)]
301 location: Location,
302 },
303
304 #[snafu(display("Failed to build mito engine"))]
305 BuildMitoEngine {
306 source: mito2::error::Error,
307 #[snafu(implicit)]
308 location: Location,
309 },
310
311 #[snafu(display("Failed to build metric engine"))]
312 BuildMetricEngine {
313 source: metric_engine::error::Error,
314 #[snafu(implicit)]
315 location: Location,
316 },
317
318 #[snafu(display("Failed to list SST entries from storage"))]
319 ListStorageSsts {
320 #[snafu(implicit)]
321 location: Location,
322 source: mito2::error::Error,
323 },
324
325 #[snafu(display("Failed to serialize options to TOML"))]
326 TomlFormat {
327 #[snafu(implicit)]
328 location: Location,
329 #[snafu(source(from(common_config::error::Error, Box::new)))]
330 source: Box<common_config::error::Error>,
331 },
332
333 #[snafu(display(
334 "Failed to get region metadata from engine {} for region_id {}",
335 engine,
336 region_id,
337 ))]
338 GetRegionMetadata {
339 engine: String,
340 region_id: RegionId,
341 #[snafu(implicit)]
342 location: Location,
343 source: BoxedError,
344 },
345
346 #[snafu(display("DataFusion"))]
347 DataFusion {
348 #[snafu(source)]
349 error: datafusion::error::DataFusionError,
350 #[snafu(implicit)]
351 location: Location,
352 },
353
354 #[snafu(display("Failed to acquire permit, source closed"))]
355 ConcurrentQueryLimiterClosed {
356 #[snafu(source)]
357 error: tokio::sync::AcquireError,
358 #[snafu(implicit)]
359 location: Location,
360 },
361
362 #[snafu(display("Failed to acquire permit under timeouts"))]
363 ConcurrentQueryLimiterTimeout {
364 #[snafu(source)]
365 error: Elapsed,
366 #[snafu(implicit)]
367 location: Location,
368 },
369
370 #[snafu(display("Cache not found in registry"))]
371 MissingCache {
372 #[snafu(implicit)]
373 location: Location,
374 },
375
376 #[snafu(display("Failed to serialize json"))]
377 SerializeJson {
378 #[snafu(source)]
379 error: serde_json::Error,
380 #[snafu(implicit)]
381 location: Location,
382 },
383
384 #[snafu(display("Failed object store operation"))]
385 ObjectStore {
386 source: object_store::error::Error,
387 #[snafu(implicit)]
388 location: Location,
389 },
390
391 #[snafu(display("Failed to build cache store"))]
392 BuildCacheStore {
393 #[snafu(source)]
394 error: object_store::Error,
395 #[snafu(implicit)]
396 location: Location,
397 },
398
399 #[snafu(display("Not yet implemented: {what}"))]
400 NotYetImplemented { what: String },
401}
402
403pub type Result<T> = std::result::Result<T, Error>;
404
405impl ErrorExt for Error {
406 fn status_code(&self) -> StatusCode {
407 use Error::*;
408 match self {
409 NewPlanDecoder { source, .. } | ExecuteLogicalPlan { source, .. } => {
410 source.status_code()
411 }
412
413 BuildRegionRequests { source, .. } => source.status_code(),
414 HandleHeartbeatResponse { source, .. } | GetMetadata { source, .. } => {
415 source.status_code()
416 }
417
418 DecodeLogicalPlan { source, .. } => source.status_code(),
419
420 Delete { source, .. } => source.status_code(),
421
422 InvalidSql { .. }
423 | IllegalPrimaryKeysDef { .. }
424 | MissingTimestampColumn { .. }
425 | SchemaNotFound { .. }
426 | SchemaExists { .. }
427 | MissingNodeId { .. }
428 | ColumnNoneDefaultValue { .. }
429 | MissingRequiredField { .. }
430 | RegionEngineNotFound { .. }
431 | ParseAddr { .. }
432 | TomlFormat { .. } => StatusCode::InvalidArguments,
433
434 PayloadNotExist { .. }
435 | Unexpected { .. }
436 | WatchAsyncTaskChange { .. }
437 | BuildHttpClient { .. } => StatusCode::Unexpected,
438
439 AsyncTaskExecute { source, .. } => source.status_code(),
440
441 CreateDir { .. } | RemoveDir { .. } | ShutdownInstance { .. } | DataFusion { .. } => {
442 StatusCode::Internal
443 }
444
445 RegionNotFound { .. } => StatusCode::RegionNotFound,
446 RegionNotReady { .. } => StatusCode::RegionNotReady,
447 RegionBusy { .. } => StatusCode::RegionBusy,
448
449 StartServer { source, .. } | ShutdownServer { source, .. } => source.status_code(),
450
451 OpenLogStore { source, .. } => source.status_code(),
452 MetaClientInit { source, .. } => source.status_code(),
453 UnsupportedOutput { .. } | NotYetImplemented { .. } => StatusCode::Unsupported,
454 HandleRegionRequest { source, .. }
455 | GetRegionMetadata { source, .. }
456 | HandleBatchOpenRequest { source, .. }
457 | HandleBatchDdlRequest { source, .. } => source.status_code(),
458 StopRegionEngine { source, .. } => source.status_code(),
459
460 FindLogicalRegions { source, .. } => source.status_code(),
461 BuildMitoEngine { source, .. } => source.status_code(),
462 BuildMetricEngine { source, .. } => source.status_code(),
463 ListStorageSsts { source, .. } => source.status_code(),
464 ConcurrentQueryLimiterClosed { .. } | ConcurrentQueryLimiterTimeout { .. } => {
465 StatusCode::RegionBusy
466 }
467 MissingCache { .. } => StatusCode::Internal,
468 SerializeJson { .. } => StatusCode::Internal,
469
470 ObjectStore { source, .. } => source.status_code(),
471 BuildCacheStore { .. } => StatusCode::StorageUnavailable,
472 }
473 }
474
475 fn as_any(&self) -> &dyn Any {
476 self
477 }
478}
479
480define_into_tonic_status!(Error);