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("Catalog not found: {}", name))]
83 CatalogNotFound {
84 name: String,
85 #[snafu(implicit)]
86 location: Location,
87 },
88
89 #[snafu(display("Schema not found: {}", name))]
90 SchemaNotFound {
91 name: String,
92 #[snafu(implicit)]
93 location: Location,
94 },
95
96 #[snafu(display("Missing timestamp column in request"))]
97 MissingTimestampColumn {
98 #[snafu(implicit)]
99 location: Location,
100 },
101
102 #[snafu(display("Failed to delete value from table: {}", table_name))]
103 Delete {
104 table_name: String,
105 #[snafu(implicit)]
106 location: Location,
107 source: TableError,
108 },
109
110 #[snafu(display("Failed to start server"))]
111 StartServer {
112 #[snafu(implicit)]
113 location: Location,
114 source: servers::error::Error,
115 },
116
117 #[snafu(display("Failed to parse address {}", addr))]
118 ParseAddr {
119 addr: String,
120 #[snafu(source)]
121 error: std::net::AddrParseError,
122 },
123
124 #[snafu(display("Failed to create directory {}", dir))]
125 CreateDir {
126 dir: String,
127 #[snafu(source)]
128 error: std::io::Error,
129 },
130
131 #[snafu(display("Failed to remove directory {}", dir))]
132 RemoveDir {
133 dir: String,
134 #[snafu(source)]
135 error: std::io::Error,
136 },
137
138 #[snafu(display("Failed to open log store"))]
139 OpenLogStore {
140 #[snafu(implicit)]
141 location: Location,
142 source: Box<log_store::error::Error>,
143 },
144
145 #[snafu(display("Failed to init backend"))]
146 InitBackend {
147 #[snafu(source)]
148 error: object_store::Error,
149 #[snafu(implicit)]
150 location: Location,
151 },
152
153 #[snafu(display("Invalid SQL, error: {}", msg))]
154 InvalidSql { msg: String },
155
156 #[snafu(display("Illegal primary keys definition: {}", msg))]
157 IllegalPrimaryKeysDef {
158 msg: String,
159 #[snafu(implicit)]
160 location: Location,
161 },
162
163 #[snafu(display("Schema {} already exists", name))]
164 SchemaExists {
165 name: String,
166 #[snafu(implicit)]
167 location: Location,
168 },
169
170 #[snafu(display("Failed to access catalog"))]
171 Catalog {
172 #[snafu(implicit)]
173 location: Location,
174 source: catalog::error::Error,
175 },
176
177 #[snafu(display("Failed to initialize meta client"))]
178 MetaClientInit {
179 #[snafu(implicit)]
180 location: Location,
181 source: meta_client::error::Error,
182 },
183
184 #[snafu(display("Missing node id in Datanode config"))]
185 MissingNodeId {
186 #[snafu(implicit)]
187 location: Location,
188 },
189
190 #[snafu(display("Failed to build http client"))]
191 BuildHttpClient {
192 #[snafu(implicit)]
193 location: Location,
194 #[snafu(source)]
195 error: reqwest::Error,
196 },
197
198 #[snafu(display("Missing required field: {}", name))]
199 MissingRequiredField {
200 name: String,
201 #[snafu(implicit)]
202 location: Location,
203 },
204
205 #[snafu(display(
206 "No valid default value can be built automatically, column: {}",
207 column,
208 ))]
209 ColumnNoneDefaultValue {
210 column: String,
211 #[snafu(implicit)]
212 location: Location,
213 },
214
215 #[snafu(display("Failed to shutdown server"))]
216 ShutdownServer {
217 #[snafu(implicit)]
218 location: Location,
219 source: servers::error::Error,
220 },
221
222 #[snafu(display("Failed to shutdown instance"))]
223 ShutdownInstance {
224 #[snafu(implicit)]
225 location: Location,
226 source: BoxedError,
227 },
228
229 #[snafu(display("Payload not exist"))]
230 PayloadNotExist {
231 #[snafu(implicit)]
232 location: Location,
233 },
234
235 #[snafu(display("Unexpected, violated: {}", violated))]
236 Unexpected {
237 violated: String,
238 #[snafu(implicit)]
239 location: Location,
240 },
241
242 #[snafu(display("Failed to handle request for region {}", region_id))]
243 HandleRegionRequest {
244 region_id: RegionId,
245 #[snafu(implicit)]
246 location: Location,
247 source: BoxedError,
248 },
249
250 #[snafu(display("Failed to open batch regions"))]
251 HandleBatchOpenRequest {
252 #[snafu(implicit)]
253 location: Location,
254 source: BoxedError,
255 },
256
257 #[snafu(display("Failed to handle batch ddl request, ddl_type: {}", ddl_type))]
258 HandleBatchDdlRequest {
259 #[snafu(implicit)]
260 location: Location,
261 source: BoxedError,
262 ddl_type: String,
263 },
264
265 #[snafu(display("RegionId {} not found", region_id))]
266 RegionNotFound {
267 region_id: RegionId,
268 #[snafu(implicit)]
269 location: Location,
270 },
271
272 #[snafu(display("Region {} not ready", region_id))]
273 RegionNotReady {
274 region_id: RegionId,
275 #[snafu(implicit)]
276 location: Location,
277 },
278
279 #[snafu(display("Region {} is busy", region_id))]
280 RegionBusy {
281 region_id: RegionId,
282 #[snafu(implicit)]
283 location: Location,
284 },
285
286 #[snafu(display("Region engine {} is not registered", name))]
287 RegionEngineNotFound {
288 name: String,
289 #[snafu(implicit)]
290 location: Location,
291 },
292
293 #[snafu(display("Unsupported output type, expected: {}", expected))]
294 UnsupportedOutput {
295 expected: String,
296 #[snafu(implicit)]
297 location: Location,
298 },
299
300 #[snafu(display("Failed to build region requests"))]
301 BuildRegionRequests {
302 #[snafu(implicit)]
303 location: Location,
304 source: store_api::metadata::MetadataError,
305 },
306
307 #[snafu(display("Failed to stop region engine {}", name))]
308 StopRegionEngine {
309 name: String,
310 #[snafu(implicit)]
311 location: Location,
312 source: BoxedError,
313 },
314
315 #[snafu(display(
316 "Failed to find logical regions in physical region {}",
317 physical_region_id
318 ))]
319 FindLogicalRegions {
320 physical_region_id: RegionId,
321 source: metric_engine::error::Error,
322 #[snafu(implicit)]
323 location: Location,
324 },
325
326 #[snafu(display("Failed to build mito engine"))]
327 BuildMitoEngine {
328 source: mito2::error::Error,
329 #[snafu(implicit)]
330 location: Location,
331 },
332
333 #[snafu(display("Failed to build metric engine"))]
334 BuildMetricEngine {
335 source: metric_engine::error::Error,
336 #[snafu(implicit)]
337 location: Location,
338 },
339
340 #[snafu(display("Failed to serialize options to TOML"))]
341 TomlFormat {
342 #[snafu(implicit)]
343 location: Location,
344 #[snafu(source(from(common_config::error::Error, Box::new)))]
345 source: Box<common_config::error::Error>,
346 },
347
348 #[snafu(display(
349 "Failed to get region metadata from engine {} for region_id {}",
350 engine,
351 region_id,
352 ))]
353 GetRegionMetadata {
354 engine: String,
355 region_id: RegionId,
356 #[snafu(implicit)]
357 location: Location,
358 source: BoxedError,
359 },
360
361 #[snafu(display("DataFusion"))]
362 DataFusion {
363 #[snafu(source)]
364 error: datafusion::error::DataFusionError,
365 #[snafu(implicit)]
366 location: Location,
367 },
368
369 #[snafu(display("Failed to acquire permit, source closed"))]
370 ConcurrentQueryLimiterClosed {
371 #[snafu(source)]
372 error: tokio::sync::AcquireError,
373 #[snafu(implicit)]
374 location: Location,
375 },
376
377 #[snafu(display("Failed to acquire permit under timeouts"))]
378 ConcurrentQueryLimiterTimeout {
379 #[snafu(source)]
380 error: Elapsed,
381 #[snafu(implicit)]
382 location: Location,
383 },
384
385 #[snafu(display("Cache not found in registry"))]
386 MissingCache {
387 #[snafu(implicit)]
388 location: Location,
389 },
390}
391
392pub type Result<T> = std::result::Result<T, Error>;
393
394impl ErrorExt for Error {
395 fn status_code(&self) -> StatusCode {
396 use Error::*;
397 match self {
398 NewPlanDecoder { source, .. } | ExecuteLogicalPlan { source, .. } => {
399 source.status_code()
400 }
401
402 BuildRegionRequests { source, .. } => source.status_code(),
403 HandleHeartbeatResponse { source, .. } | GetMetadata { source, .. } => {
404 source.status_code()
405 }
406
407 DecodeLogicalPlan { source, .. } => source.status_code(),
408
409 Delete { source, .. } => source.status_code(),
410
411 InvalidSql { .. }
412 | IllegalPrimaryKeysDef { .. }
413 | MissingTimestampColumn { .. }
414 | CatalogNotFound { .. }
415 | SchemaNotFound { .. }
416 | SchemaExists { .. }
417 | MissingNodeId { .. }
418 | ColumnNoneDefaultValue { .. }
419 | Catalog { .. }
420 | MissingRequiredField { .. }
421 | RegionEngineNotFound { .. }
422 | ParseAddr { .. }
423 | TomlFormat { .. } => StatusCode::InvalidArguments,
424
425 PayloadNotExist { .. }
426 | Unexpected { .. }
427 | WatchAsyncTaskChange { .. }
428 | BuildHttpClient { .. } => StatusCode::Unexpected,
429
430 AsyncTaskExecute { source, .. } => source.status_code(),
431
432 CreateDir { .. } | RemoveDir { .. } | ShutdownInstance { .. } | DataFusion { .. } => {
433 StatusCode::Internal
434 }
435
436 RegionNotFound { .. } => StatusCode::RegionNotFound,
437 RegionNotReady { .. } => StatusCode::RegionNotReady,
438 RegionBusy { .. } => StatusCode::RegionBusy,
439
440 StartServer { source, .. } | ShutdownServer { source, .. } => source.status_code(),
441
442 InitBackend { .. } => StatusCode::StorageUnavailable,
443
444 OpenLogStore { source, .. } => source.status_code(),
445 MetaClientInit { source, .. } => source.status_code(),
446 UnsupportedOutput { .. } => StatusCode::Unsupported,
447 HandleRegionRequest { source, .. }
448 | GetRegionMetadata { source, .. }
449 | HandleBatchOpenRequest { source, .. }
450 | HandleBatchDdlRequest { source, .. } => source.status_code(),
451 StopRegionEngine { source, .. } => source.status_code(),
452
453 FindLogicalRegions { source, .. } => source.status_code(),
454 BuildMitoEngine { source, .. } => source.status_code(),
455 BuildMetricEngine { source, .. } => source.status_code(),
456 ConcurrentQueryLimiterClosed { .. } | ConcurrentQueryLimiterTimeout { .. } => {
457 StatusCode::RegionBusy
458 }
459 MissingCache { .. } => StatusCode::Internal,
460 }
461 }
462
463 fn as_any(&self) -> &dyn Any {
464 self
465 }
466}
467
468define_into_tonic_status!(Error);