1use std::any::Any;
16
17use common_datasource::file_format::Format;
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 common_query::error::datafusion_status_code;
23use datafusion::error::DataFusionError;
24use session::ReadPreference;
25use snafu::{Location, Snafu};
26use store_api::storage::RegionId;
27
28#[derive(Snafu)]
29#[snafu(visibility(pub))]
30#[stack_trace_debug]
31pub enum Error {
32 #[snafu(display("Failed to invalidate table cache"))]
33 InvalidateTableCache {
34 #[snafu(implicit)]
35 location: Location,
36 source: common_meta::error::Error,
37 },
38
39 #[snafu(display("Failed to handle heartbeat response"))]
40 HandleHeartbeatResponse {
41 #[snafu(implicit)]
42 location: Location,
43 source: common_meta::error::Error,
44 },
45
46 #[snafu(display("External error"))]
47 External {
48 #[snafu(implicit)]
49 location: Location,
50 source: BoxedError,
51 },
52
53 #[snafu(display("Failed to query"))]
54 RequestQuery {
55 #[snafu(implicit)]
56 location: Location,
57 source: common_meta::error::Error,
58 },
59
60 #[snafu(display("Failed to start server"))]
61 StartServer {
62 #[snafu(implicit)]
63 location: Location,
64 source: servers::error::Error,
65 },
66
67 #[snafu(display("Failed to shutdown server"))]
68 ShutdownServer {
69 #[snafu(implicit)]
70 location: Location,
71 source: servers::error::Error,
72 },
73
74 #[snafu(display("Failed to parse address {}", addr))]
75 ParseAddr {
76 addr: String,
77 #[snafu(source)]
78 error: std::net::AddrParseError,
79 },
80
81 #[snafu(display("Failed to parse SQL"))]
82 ParseSql {
83 #[snafu(implicit)]
84 location: Location,
85 source: sql::error::Error,
86 },
87
88 #[snafu(display("Invalid SQL, error: {}", err_msg))]
89 InvalidSql {
90 err_msg: String,
91 #[snafu(implicit)]
92 location: Location,
93 },
94
95 #[snafu(display("Incomplete GRPC request: {}", err_msg))]
96 IncompleteGrpcRequest {
97 err_msg: String,
98 #[snafu(implicit)]
99 location: Location,
100 },
101
102 #[snafu(display("Invalid InsertRequest, reason: {}", reason))]
103 InvalidInsertRequest {
104 reason: String,
105 #[snafu(implicit)]
106 location: Location,
107 },
108
109 #[snafu(display("Invalid DeleteRequest, reason: {}", reason))]
110 InvalidDeleteRequest {
111 reason: String,
112 #[snafu(implicit)]
113 location: Location,
114 },
115
116 #[snafu(display("Table not found: {}", table_name))]
117 TableNotFound { table_name: String },
118
119 #[snafu(display("General catalog error"))]
120 Catalog {
121 #[snafu(implicit)]
122 location: Location,
123 source: catalog::error::Error,
124 },
125
126 #[snafu(display("Failed to create heartbeat stream to Metasrv"))]
127 CreateMetaHeartbeatStream {
128 source: meta_client::error::Error,
129 #[snafu(implicit)]
130 location: Location,
131 },
132
133 #[snafu(display(
134 "Failed to find region peer for region id {}, read preference: {}",
135 region_id,
136 read_preference
137 ))]
138 FindRegionPeer {
139 region_id: RegionId,
140 read_preference: ReadPreference,
141 #[snafu(implicit)]
142 location: Location,
143 source: partition::error::Error,
144 },
145
146 #[snafu(display("Schema {} already exists", name))]
147 SchemaExists {
148 name: String,
149 #[snafu(implicit)]
150 location: Location,
151 },
152
153 #[snafu(display("Table occurs error"))]
154 Table {
155 #[snafu(implicit)]
156 location: Location,
157 source: table::error::Error,
158 },
159
160 #[snafu(display("Cannot find column by name: {}", msg))]
161 ColumnNotFound {
162 msg: String,
163 #[snafu(implicit)]
164 location: Location,
165 },
166
167 #[snafu(display("Failed to collect recordbatch"))]
168 CollectRecordbatch {
169 #[snafu(implicit)]
170 location: Location,
171 source: common_recordbatch::error::Error,
172 },
173
174 #[snafu(display("Failed to plan statement"))]
175 PlanStatement {
176 #[snafu(implicit)]
177 location: Location,
178 source: query::error::Error,
179 },
180
181 #[snafu(display("Failed to read table: {table_name}"))]
182 ReadTable {
183 table_name: String,
184 #[snafu(implicit)]
185 location: Location,
186 source: query::error::Error,
187 },
188
189 #[snafu(display("Failed to execute logical plan"))]
190 ExecLogicalPlan {
191 #[snafu(implicit)]
192 location: Location,
193 source: query::error::Error,
194 },
195
196 #[snafu(display("Operation to region server failed"))]
197 InvokeRegionServer {
198 #[snafu(implicit)]
199 location: Location,
200 source: servers::error::Error,
201 },
202
203 #[snafu(display("Not supported: {}", feat))]
204 NotSupported { feat: String },
205
206 #[snafu(display("SQL execution intercepted"))]
207 SqlExecIntercepted {
208 #[snafu(implicit)]
209 location: Location,
210 source: BoxedError,
211 },
212
213 #[snafu(display("Failed to execute PromQL query {}", query))]
215 ExecutePromql {
216 query: String,
217 #[snafu(implicit)]
218 location: Location,
219 source: servers::error::Error,
220 },
221
222 #[snafu(display("Failed to create logical plan for prometheus query"))]
223 PromStoreRemoteQueryPlan {
224 #[snafu(implicit)]
225 location: Location,
226 source: servers::error::Error,
227 },
228
229 #[snafu(display("Failed to create logical plan for prometheus metric names query"))]
230 PrometheusMetricNamesQueryPlan {
231 #[snafu(implicit)]
232 location: Location,
233 source: servers::error::Error,
234 },
235
236 #[snafu(display("Failed to create logical plan for prometheus label values query"))]
237 PrometheusLabelValuesQueryPlan {
238 #[snafu(implicit)]
239 location: Location,
240 source: query::promql::error::Error,
241 },
242
243 #[snafu(display("Failed to describe schema for given statement"))]
244 DescribeStatement {
245 #[snafu(implicit)]
246 location: Location,
247 source: query::error::Error,
248 },
249
250 #[snafu(display("Illegal primary keys definition: {}", msg))]
251 IllegalPrimaryKeysDef {
252 msg: String,
253 #[snafu(implicit)]
254 location: Location,
255 },
256
257 #[snafu(display("Failed to insert value into table: {}", table_name))]
258 Insert {
259 table_name: String,
260 #[snafu(implicit)]
261 location: Location,
262 source: table::error::Error,
263 },
264
265 #[snafu(display("Unsupported format: {:?}", format))]
266 UnsupportedFormat {
267 #[snafu(implicit)]
268 location: Location,
269 format: Format,
270 },
271
272 #[snafu(display("Failed to pass permission check"))]
273 Permission {
274 source: auth::error::Error,
275 #[snafu(implicit)]
276 location: Location,
277 },
278
279 #[snafu(display(
280 "No valid default value can be built automatically, column: {}",
281 column,
282 ))]
283 ColumnNoneDefaultValue {
284 column: String,
285 #[snafu(implicit)]
286 location: Location,
287 },
288
289 #[snafu(display("Invalid region request, reason: {}", reason))]
290 InvalidRegionRequest { reason: String },
291
292 #[snafu(display("Table operation error"))]
293 TableOperation {
294 source: operator::error::Error,
295 #[snafu(implicit)]
296 location: Location,
297 },
298
299 #[snafu(display("Invalid auth config"))]
300 IllegalAuthConfig { source: auth::error::Error },
301
302 #[snafu(display("Failed to serialize options to TOML"))]
303 TomlFormat {
304 #[snafu(implicit)]
305 location: Location,
306 #[snafu(source(from(common_config::error::Error, Box::new)))]
307 source: Box<common_config::error::Error>,
308 },
309
310 #[snafu(display("Failed to get cache from cache registry: {}", name))]
311 CacheRequired {
312 #[snafu(implicit)]
313 location: Location,
314 name: String,
315 },
316
317 #[snafu(display("Invalid tls config"))]
318 InvalidTlsConfig {
319 #[snafu(source)]
320 error: common_grpc::error::Error,
321 #[snafu(implicit)]
322 location: Location,
323 },
324
325 #[snafu(display("Failed to init plugin"))]
326 InitPlugin {
328 #[snafu(implicit)]
329 location: Location,
330 source: BoxedError,
331 },
332
333 #[snafu(display("Failed to decode logical plan from substrait"))]
334 SubstraitDecodeLogicalPlan {
335 #[snafu(implicit)]
336 location: Location,
337 source: common_query::error::Error,
338 },
339
340 #[snafu(display("DataFusionError"))]
341 DataFusion {
342 #[snafu(source)]
343 error: DataFusionError,
344 #[snafu(implicit)]
345 location: Location,
346 },
347
348 #[snafu(display("Query has been cancelled"))]
349 Cancelled {
350 #[snafu(implicit)]
351 location: Location,
352 },
353
354 #[snafu(display("Canceling statement due to statement timeout"))]
355 StatementTimeout {
356 #[snafu(implicit)]
357 location: Location,
358 },
359
360 #[snafu(display("Failed to acquire more permits from limiter"))]
361 AcquireLimiter {
362 #[snafu(source)]
363 error: tokio::sync::AcquireError,
364 #[snafu(implicit)]
365 location: Location,
366 },
367}
368
369pub type Result<T> = std::result::Result<T, Error>;
370
371impl ErrorExt for Error {
372 fn status_code(&self) -> StatusCode {
373 match self {
374 Error::TomlFormat { .. }
375 | Error::ParseAddr { .. }
376 | Error::InvalidSql { .. }
377 | Error::InvalidInsertRequest { .. }
378 | Error::InvalidDeleteRequest { .. }
379 | Error::IllegalPrimaryKeysDef { .. }
380 | Error::SchemaExists { .. }
381 | Error::ColumnNotFound { .. }
382 | Error::UnsupportedFormat { .. }
383 | Error::IllegalAuthConfig { .. }
384 | Error::ColumnNoneDefaultValue { .. }
385 | Error::IncompleteGrpcRequest { .. }
386 | Error::InvalidTlsConfig { .. } => StatusCode::InvalidArguments,
387
388 Error::NotSupported { .. } => StatusCode::Unsupported,
389
390 Error::Permission { source, .. } => source.status_code(),
391
392 Error::DescribeStatement { source, .. } => source.status_code(),
393
394 Error::HandleHeartbeatResponse { source, .. } => source.status_code(),
395
396 Error::PromStoreRemoteQueryPlan { source, .. }
397 | Error::PrometheusMetricNamesQueryPlan { source, .. }
398 | Error::ExecutePromql { source, .. } => source.status_code(),
399
400 Error::SubstraitDecodeLogicalPlan { source, .. } => source.status_code(),
401
402 Error::PrometheusLabelValuesQueryPlan { source, .. } => source.status_code(),
403
404 Error::CollectRecordbatch { .. } => StatusCode::EngineExecuteQuery,
405
406 Error::SqlExecIntercepted { source, .. } => source.status_code(),
407 Error::StartServer { source, .. } => source.status_code(),
408 Error::ShutdownServer { source, .. } => source.status_code(),
409
410 Error::ParseSql { source, .. } => source.status_code(),
411
412 Error::InvalidateTableCache { source, .. } => source.status_code(),
413
414 Error::Table { source, .. } | Error::Insert { source, .. } => source.status_code(),
415
416 Error::RequestQuery { source, .. } => source.status_code(),
417
418 Error::CacheRequired { .. } => StatusCode::Internal,
419
420 Error::InvalidRegionRequest { .. } => StatusCode::IllegalState,
421
422 Error::TableNotFound { .. } => StatusCode::TableNotFound,
423
424 Error::Catalog { source, .. } => source.status_code(),
425
426 Error::CreateMetaHeartbeatStream { source, .. } => source.status_code(),
427
428 Error::PlanStatement { source, .. }
429 | Error::ReadTable { source, .. }
430 | Error::ExecLogicalPlan { source, .. } => source.status_code(),
431
432 Error::InvokeRegionServer { source, .. } => source.status_code(),
433 Error::External { source, .. } | Error::InitPlugin { source, .. } => {
434 source.status_code()
435 }
436 Error::FindRegionPeer { source, .. } => source.status_code(),
437
438 Error::TableOperation { source, .. } => source.status_code(),
439
440 Error::DataFusion { error, .. } => datafusion_status_code::<Self>(error, None),
441
442 Error::Cancelled { .. } => StatusCode::Cancelled,
443
444 Error::StatementTimeout { .. } => StatusCode::Cancelled,
445
446 Error::AcquireLimiter { .. } => StatusCode::Internal,
447 }
448 }
449
450 fn as_any(&self) -> &dyn Any {
451 self
452 }
453}
454
455define_into_tonic_status!(Error);
456
457impl From<operator::error::Error> for Error {
458 fn from(e: operator::error::Error) -> Error {
459 Error::TableOperation {
460 source: e,
461 location: Location::default(),
462 }
463 }
464}