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