1use std::any::Any;
16use std::net::SocketAddr;
17use std::string::FromUtf8Error;
18
19use axum::http::StatusCode as HttpStatusCode;
20use axum::response::{IntoResponse, Response};
21use axum::{Json, http};
22use base64::DecodeError;
23use common_base::readable_size::ReadableSize;
24use common_error::define_into_tonic_status;
25use common_error::ext::{BoxedError, ErrorExt};
26use common_error::status_code::StatusCode;
27use common_macro::stack_trace_debug;
28use common_telemetry::{error, warn};
29use datafusion::error::DataFusionError;
30use datatypes::prelude::ConcreteDataType;
31use headers::ContentType;
32use http::header::InvalidHeaderValue;
33use query::parser::PromQuery;
34use serde_json::json;
35use snafu::{Location, Snafu};
36
37#[derive(Snafu)]
38#[snafu(visibility(pub))]
39#[stack_trace_debug]
40pub enum Error {
41 #[snafu(display("Failed to bind address: {}", addr))]
42 AddressBind {
43 addr: SocketAddr,
44 #[snafu(source)]
45 error: std::io::Error,
46 #[snafu(implicit)]
47 location: Location,
48 },
49
50 #[snafu(display("Arrow error"))]
51 Arrow {
52 #[snafu(source)]
53 error: arrow_schema::ArrowError,
54 },
55
56 #[snafu(display("Internal error: {}", err_msg))]
57 Internal { err_msg: String },
58
59 #[snafu(display("Unsupported data type: {}, reason: {}", data_type, reason))]
60 UnsupportedDataType {
61 data_type: ConcreteDataType,
62 reason: String,
63 },
64
65 #[snafu(display("Internal IO error"))]
66 InternalIo {
67 #[snafu(source)]
68 error: std::io::Error,
69 },
70
71 #[snafu(display("Tokio IO error: {}", err_msg))]
72 TokioIo {
73 err_msg: String,
74 #[snafu(source)]
75 error: std::io::Error,
76 },
77
78 #[snafu(display("Failed to collect recordbatch"))]
79 CollectRecordbatch {
80 #[snafu(implicit)]
81 location: Location,
82 source: common_recordbatch::error::Error,
83 },
84
85 #[snafu(display("Failed to start HTTP server"))]
86 StartHttp {
87 #[snafu(source)]
88 error: hyper::Error,
89 },
90
91 #[snafu(display("Failed to start gRPC server"))]
92 StartGrpc {
93 #[snafu(source)]
94 error: tonic::transport::Error,
95 },
96
97 #[snafu(display("Request memory limit exceeded"))]
98 MemoryLimitExceeded {
99 #[snafu(implicit)]
100 location: Location,
101 source: common_memory_manager::Error,
102 },
103
104 #[snafu(display("{} server is already started", server))]
105 AlreadyStarted {
106 server: String,
107 #[snafu(implicit)]
108 location: Location,
109 },
110
111 #[snafu(display("Failed to bind address {}", addr))]
112 TcpBind {
113 addr: SocketAddr,
114 #[snafu(source)]
115 error: std::io::Error,
116 },
117
118 #[snafu(display("Failed to execute query"))]
119 ExecuteQuery {
120 #[snafu(implicit)]
121 location: Location,
122 source: BoxedError,
123 },
124
125 #[snafu(display("Failed to execute plan"))]
126 ExecutePlan {
127 #[snafu(implicit)]
128 location: Location,
129 source: BoxedError,
130 },
131
132 #[snafu(display("Execute gRPC query error"))]
133 ExecuteGrpcQuery {
134 #[snafu(implicit)]
135 location: Location,
136 source: BoxedError,
137 },
138
139 #[snafu(display("Execute gRPC request error"))]
140 ExecuteGrpcRequest {
141 #[snafu(implicit)]
142 location: Location,
143 source: BoxedError,
144 },
145
146 #[snafu(display("Failed to check database validity"))]
147 CheckDatabaseValidity {
148 #[snafu(implicit)]
149 location: Location,
150 source: BoxedError,
151 },
152
153 #[snafu(display("Failed to describe statement"))]
154 DescribeStatement { source: BoxedError },
155
156 #[snafu(display("Pipeline error"))]
157 Pipeline {
158 #[snafu(source)]
159 source: pipeline::error::Error,
160 #[snafu(implicit)]
161 location: Location,
162 },
163
164 #[snafu(display("Not supported: {}", feat))]
165 NotSupported { feat: String },
166
167 #[snafu(display("Invalid request parameter: {}", reason))]
168 InvalidParameter {
169 reason: String,
170 #[snafu(implicit)]
171 location: Location,
172 },
173
174 #[snafu(display(
175 "Too many concurrent large requests, limit: {}, request size: {}",
176 ReadableSize(*limit as u64),
177 ReadableSize(*request_size as u64)
178 ))]
179 TooManyConcurrentRequests {
180 limit: usize,
181 request_size: usize,
182 #[snafu(implicit)]
183 location: Location,
184 },
185
186 #[snafu(display("Invalid query: {}", reason))]
187 InvalidQuery {
188 reason: String,
189 #[snafu(implicit)]
190 location: Location,
191 },
192
193 #[snafu(display("Failed to parse query"))]
194 FailedToParseQuery {
195 #[snafu(implicit)]
196 location: Location,
197 source: sql::error::Error,
198 },
199
200 #[snafu(display("Failed to parse InfluxDB line protocol"))]
201 InfluxdbLineProtocol {
202 #[snafu(implicit)]
203 location: Location,
204 #[snafu(source)]
205 error: influxdb_line_protocol::Error,
206 },
207
208 #[snafu(display("Failed to write row"))]
209 RowWriter {
210 #[snafu(implicit)]
211 location: Location,
212 source: common_grpc::error::Error,
213 },
214
215 #[snafu(display("Failed to convert time precision, name: {}", name))]
216 TimePrecision {
217 name: String,
218 #[snafu(implicit)]
219 location: Location,
220 },
221
222 #[snafu(display("Invalid OpenTSDB Json request"))]
223 InvalidOpentsdbJsonRequest {
224 #[snafu(source)]
225 error: serde_json::error::Error,
226 #[snafu(implicit)]
227 location: Location,
228 },
229
230 #[snafu(display("Failed to decode prometheus remote request"))]
231 DecodePromRemoteRequest {
232 #[snafu(implicit)]
233 location: Location,
234 #[snafu(source)]
235 error: prost::DecodeError,
236 },
237
238 #[snafu(display(
239 "Failed to decode OTLP request (content-type: {content_type}): {error}. The endpoint only accepts 'application/x-protobuf' format."
240 ))]
241 DecodeOtlpRequest {
242 content_type: String,
243 #[snafu(implicit)]
244 location: Location,
245 #[snafu(source)]
246 error: prost::DecodeError,
247 },
248
249 #[snafu(display("Failed to decode Loki request: {error}"))]
250 DecodeLokiRequest {
251 #[snafu(implicit)]
252 location: Location,
253 #[snafu(source)]
254 error: prost::DecodeError,
255 },
256
257 #[snafu(display(
258 "Unsupported content type 'application/json'. OTLP endpoint only supports 'application/x-protobuf'. Please configure your OTLP exporter to use protobuf encoding."
259 ))]
260 UnsupportedJsonContentType {
261 #[snafu(implicit)]
262 location: Location,
263 },
264
265 #[snafu(display(
266 "OTLP metric input have incompatible existing tables, please refer to docs for details"
267 ))]
268 OtlpMetricModeIncompatible {
269 #[snafu(implicit)]
270 location: Location,
271 },
272
273 #[snafu(display("Common Meta error"))]
274 CommonMeta {
275 #[snafu(implicit)]
276 location: Location,
277 #[snafu(source)]
278 source: common_meta::error::Error,
279 },
280
281 #[snafu(display("Failed to decompress snappy prometheus remote request"))]
282 DecompressSnappyPromRemoteRequest {
283 #[snafu(implicit)]
284 location: Location,
285 #[snafu(source)]
286 error: snap::Error,
287 },
288
289 #[snafu(display("Failed to decompress zstd prometheus remote request"))]
290 DecompressZstdPromRemoteRequest {
291 #[snafu(implicit)]
292 location: Location,
293 #[snafu(source)]
294 error: std::io::Error,
295 },
296
297 #[snafu(display("Failed to compress prometheus remote request"))]
298 CompressPromRemoteRequest {
299 #[snafu(implicit)]
300 location: Location,
301 #[snafu(source)]
302 error: snap::Error,
303 },
304
305 #[snafu(display("Invalid prometheus remote request, msg: {}", msg))]
306 InvalidPromRemoteRequest {
307 msg: String,
308 #[snafu(implicit)]
309 location: Location,
310 },
311
312 #[snafu(display("Invalid prometheus remote read query result, msg: {}", msg))]
313 InvalidPromRemoteReadQueryResult {
314 msg: String,
315 #[snafu(implicit)]
316 location: Location,
317 },
318
319 #[snafu(display("Invalid Flight ticket"))]
320 InvalidFlightTicket {
321 #[snafu(source)]
322 error: api::DecodeError,
323 #[snafu(implicit)]
324 location: Location,
325 },
326
327 #[snafu(display("Tls is required for {}, plain connection is rejected", server))]
328 TlsRequired { server: String },
329
330 #[snafu(display("Failed to get user info"))]
331 Auth {
332 #[snafu(implicit)]
333 location: Location,
334 source: auth::error::Error,
335 },
336
337 #[snafu(display("Not found http or grpc authorization header"))]
338 NotFoundAuthHeader {},
339
340 #[snafu(display("Not found influx http authorization info"))]
341 NotFoundInfluxAuth {},
342
343 #[snafu(display("Unsupported http auth scheme, name: {}", name))]
344 UnsupportedAuthScheme { name: String },
345
346 #[snafu(display("Invalid visibility ASCII chars"))]
347 InvalidAuthHeaderInvisibleASCII {
348 #[snafu(source)]
349 error: hyper::header::ToStrError,
350 #[snafu(implicit)]
351 location: Location,
352 },
353
354 #[snafu(display("Invalid utf-8 value"))]
355 InvalidAuthHeaderInvalidUtf8Value {
356 #[snafu(source)]
357 error: FromUtf8Error,
358 #[snafu(implicit)]
359 location: Location,
360 },
361
362 #[snafu(display("Invalid http authorization header"))]
363 InvalidAuthHeader {
364 #[snafu(implicit)]
365 location: Location,
366 },
367
368 #[snafu(display("Invalid base64 value"))]
369 InvalidBase64Value {
370 #[snafu(source)]
371 error: DecodeError,
372 #[snafu(implicit)]
373 location: Location,
374 },
375
376 #[snafu(display("Invalid utf-8 value"))]
377 InvalidUtf8Value {
378 #[snafu(source)]
379 error: FromUtf8Error,
380 #[snafu(implicit)]
381 location: Location,
382 },
383
384 #[snafu(display("Invalid http header value"))]
385 InvalidHeaderValue {
386 #[snafu(source)]
387 error: InvalidHeaderValue,
388 #[snafu(implicit)]
389 location: Location,
390 },
391
392 #[snafu(display("Error accessing catalog"))]
393 Catalog {
394 source: catalog::error::Error,
395 #[snafu(implicit)]
396 location: Location,
397 },
398
399 #[snafu(display("Cannot find requested table: {}.{}.{}", catalog, schema, table))]
400 TableNotFound {
401 catalog: String,
402 schema: String,
403 table: String,
404 #[snafu(implicit)]
405 location: Location,
406 },
407
408 #[cfg(feature = "mem-prof")]
409 #[snafu(display("Failed to dump profile data"))]
410 DumpProfileData {
411 #[snafu(implicit)]
412 location: Location,
413 source: common_mem_prof::error::Error,
414 },
415
416 #[snafu(display("Invalid prepare statement: {}", err_msg))]
417 InvalidPrepareStatement {
418 err_msg: String,
419 #[snafu(implicit)]
420 location: Location,
421 },
422
423 #[snafu(display("Failed to build HTTP response"))]
424 BuildHttpResponse {
425 #[snafu(source)]
426 error: http::Error,
427 #[snafu(implicit)]
428 location: Location,
429 },
430
431 #[snafu(display("Failed to parse PromQL: {query:?}"))]
432 ParsePromQL {
433 query: Box<PromQuery>,
434 #[snafu(implicit)]
435 location: Location,
436 source: query::error::Error,
437 },
438
439 #[snafu(display("Failed to parse timestamp: {}", timestamp))]
440 ParseTimestamp {
441 timestamp: String,
442 #[snafu(implicit)]
443 location: Location,
444 #[snafu(source)]
445 error: query::error::Error,
446 },
447
448 #[snafu(display("{}", reason))]
449 UnexpectedResult {
450 reason: String,
451 #[snafu(implicit)]
452 location: Location,
453 },
454
455 #[snafu(display("Other error"))]
458 Other {
459 source: BoxedError,
460 #[snafu(implicit)]
461 location: Location,
462 },
463
464 #[snafu(display("Failed to join task"))]
465 JoinTask {
466 #[snafu(source)]
467 error: tokio::task::JoinError,
468 #[snafu(implicit)]
469 location: Location,
470 },
471
472 #[cfg(feature = "pprof")]
473 #[snafu(display("Failed to dump pprof data"))]
474 DumpPprof { source: common_pprof::error::Error },
475
476 #[cfg(not(windows))]
477 #[snafu(display("Failed to update jemalloc metrics"))]
478 UpdateJemallocMetrics {
479 #[snafu(source)]
480 error: tikv_jemalloc_ctl::Error,
481 #[snafu(implicit)]
482 location: Location,
483 },
484
485 #[snafu(display("DataFrame operation error"))]
486 DataFrame {
487 #[snafu(source)]
488 error: datafusion::error::DataFusionError,
489 #[snafu(implicit)]
490 location: Location,
491 },
492
493 #[snafu(display("Failed to convert scalar value"))]
494 ConvertScalarValue {
495 source: datatypes::error::Error,
496 #[snafu(implicit)]
497 location: Location,
498 },
499
500 #[snafu(display("Expected type: {:?}, actual: {:?}", expected, actual))]
501 PreparedStmtTypeMismatch {
502 expected: ConcreteDataType,
503 actual: opensrv_mysql::ColumnType,
504 #[snafu(implicit)]
505 location: Location,
506 },
507
508 #[snafu(display(
509 "Column: {}, {} incompatible, expected: {}, actual: {}",
510 column_name,
511 datatype,
512 expected,
513 actual
514 ))]
515 IncompatibleSchema {
516 column_name: String,
517 datatype: String,
518 expected: i32,
519 actual: i32,
520 #[snafu(implicit)]
521 location: Location,
522 },
523
524 #[snafu(display("Failed to convert to json"))]
525 ToJson {
526 #[snafu(source)]
527 error: serde_json::error::Error,
528 #[snafu(implicit)]
529 location: Location,
530 },
531
532 #[snafu(display("Failed to parse payload as json"))]
533 ParseJson {
534 #[snafu(source)]
535 error: serde_json::error::Error,
536 #[snafu(implicit)]
537 location: Location,
538 },
539
540 #[snafu(display("Invalid Loki labels: {}", msg))]
541 InvalidLokiLabels {
542 msg: String,
543 #[snafu(implicit)]
544 location: Location,
545 },
546
547 #[snafu(display("Invalid Loki JSON request: {}", msg))]
548 InvalidLokiPayload {
549 msg: String,
550 #[snafu(implicit)]
551 location: Location,
552 },
553
554 #[snafu(display("Unsupported content type: {:?}", content_type))]
555 UnsupportedContentType {
556 content_type: ContentType,
557 #[snafu(implicit)]
558 location: Location,
559 },
560
561 #[snafu(display("Failed to decode url"))]
562 UrlDecode {
563 #[snafu(source)]
564 error: FromUtf8Error,
565 #[snafu(implicit)]
566 location: Location,
567 },
568
569 #[snafu(display("Failed to convert Mysql value, error: {}", err_msg))]
570 MysqlValueConversion {
571 err_msg: String,
572 #[snafu(implicit)]
573 location: Location,
574 },
575
576 #[snafu(display("Invalid table name"))]
577 InvalidTableName {
578 #[snafu(source)]
579 error: tonic::metadata::errors::ToStrError,
580 #[snafu(implicit)]
581 location: Location,
582 },
583
584 #[snafu(display("Failed to initialize a watcher for file {}", path))]
585 FileWatch {
586 path: String,
587 #[snafu(source)]
588 error: notify::Error,
589 },
590
591 #[snafu(display("Timestamp overflow: {}", error))]
592 TimestampOverflow {
593 error: String,
594 #[snafu(implicit)]
595 location: Location,
596 },
597
598 #[snafu(display("Unsupported json data type for tag: {} {}", key, ty))]
599 UnsupportedJsonDataTypeForTag {
600 key: String,
601 ty: String,
602 #[snafu(implicit)]
603 location: Location,
604 },
605
606 #[snafu(display("Convert SQL value error"))]
607 ConvertSqlValue {
608 source: datatypes::error::Error,
609 #[snafu(implicit)]
610 location: Location,
611 },
612
613 #[snafu(display("Prepare statement not found: {}", name))]
614 PrepareStatementNotFound {
615 name: String,
616 #[snafu(implicit)]
617 location: Location,
618 },
619
620 #[snafu(display("Invalid elasticsearch input, reason: {}", reason))]
621 InvalidElasticsearchInput {
622 reason: String,
623 #[snafu(implicit)]
624 location: Location,
625 },
626
627 #[snafu(display("Invalid Jaeger query, reason: {}", reason))]
628 InvalidJaegerQuery {
629 reason: String,
630 #[snafu(implicit)]
631 location: Location,
632 },
633
634 #[snafu(display("DataFusion error"))]
635 DataFusion {
636 #[snafu(source)]
637 error: DataFusionError,
638 #[snafu(implicit)]
639 location: Location,
640 },
641
642 #[snafu(display("Failed to handle otel-arrow request, error message: {}", err_msg))]
643 HandleOtelArrowRequest {
644 err_msg: String,
645 #[snafu(implicit)]
646 location: Location,
647 },
648
649 #[snafu(display("Unknown hint: {}", hint))]
650 UnknownHint { hint: String },
651
652 #[snafu(display("Query has been cancelled"))]
653 Cancelled {
654 #[snafu(implicit)]
655 location: Location,
656 },
657
658 #[snafu(display("Service suspended"))]
659 Suspended {
660 #[snafu(implicit)]
661 location: Location,
662 },
663
664 #[snafu(transparent)]
665 GreptimeProto {
666 source: api::error::Error,
667 #[snafu(implicit)]
668 location: Location,
669 },
670}
671
672pub type Result<T, E = Error> = std::result::Result<T, E>;
673
674impl ErrorExt for Error {
675 fn status_code(&self) -> StatusCode {
676 use Error::*;
677 match self {
678 Internal { .. }
679 | InternalIo { .. }
680 | TokioIo { .. }
681 | StartHttp { .. }
682 | StartGrpc { .. }
683 | TcpBind { .. }
684 | BuildHttpResponse { .. }
685 | Arrow { .. }
686 | FileWatch { .. } => StatusCode::Internal,
687
688 AddressBind { .. }
689 | AlreadyStarted { .. }
690 | InvalidPromRemoteReadQueryResult { .. }
691 | OtlpMetricModeIncompatible { .. } => StatusCode::IllegalState,
692
693 UnsupportedDataType { .. } => StatusCode::Unsupported,
694
695 #[cfg(not(windows))]
696 UpdateJemallocMetrics { .. } => StatusCode::Internal,
697
698 CollectRecordbatch { .. } => StatusCode::EngineExecuteQuery,
699
700 ExecuteQuery { source, .. }
701 | ExecutePlan { source, .. }
702 | ExecuteGrpcQuery { source, .. }
703 | ExecuteGrpcRequest { source, .. }
704 | CheckDatabaseValidity { source, .. } => source.status_code(),
705
706 Pipeline { source, .. } => source.status_code(),
707 CommonMeta { source, .. } => source.status_code(),
708
709 NotSupported { .. }
710 | InvalidParameter { .. }
711 | InvalidQuery { .. }
712 | InfluxdbLineProtocol { .. }
713 | InvalidOpentsdbJsonRequest { .. }
714 | DecodePromRemoteRequest { .. }
715 | DecodeOtlpRequest { .. }
716 | DecodeLokiRequest { .. }
717 | UnsupportedJsonContentType { .. }
718 | CompressPromRemoteRequest { .. }
719 | DecompressSnappyPromRemoteRequest { .. }
720 | DecompressZstdPromRemoteRequest { .. }
721 | InvalidPromRemoteRequest { .. }
722 | InvalidFlightTicket { .. }
723 | InvalidPrepareStatement { .. }
724 | DataFrame { .. }
725 | PreparedStmtTypeMismatch { .. }
726 | TimePrecision { .. }
727 | UrlDecode { .. }
728 | IncompatibleSchema { .. }
729 | MysqlValueConversion { .. }
730 | ParseJson { .. }
731 | InvalidLokiLabels { .. }
732 | InvalidLokiPayload { .. }
733 | UnsupportedContentType { .. }
734 | TimestampOverflow { .. }
735 | UnsupportedJsonDataTypeForTag { .. }
736 | InvalidTableName { .. }
737 | PrepareStatementNotFound { .. }
738 | FailedToParseQuery { .. }
739 | InvalidElasticsearchInput { .. }
740 | InvalidJaegerQuery { .. }
741 | ParseTimestamp { .. }
742 | UnknownHint { .. } => StatusCode::InvalidArguments,
743
744 Catalog { source, .. } => source.status_code(),
745 RowWriter { source, .. } => source.status_code(),
746
747 TlsRequired { .. } => StatusCode::Unknown,
748 Auth { source, .. } => source.status_code(),
749 DescribeStatement { source } => source.status_code(),
750
751 NotFoundAuthHeader { .. } | NotFoundInfluxAuth { .. } => StatusCode::AuthHeaderNotFound,
752 InvalidAuthHeaderInvisibleASCII { .. }
753 | UnsupportedAuthScheme { .. }
754 | InvalidAuthHeader { .. }
755 | InvalidBase64Value { .. }
756 | InvalidAuthHeaderInvalidUtf8Value { .. } => StatusCode::InvalidAuthHeader,
757
758 TableNotFound { .. } => StatusCode::TableNotFound,
759
760 #[cfg(feature = "mem-prof")]
761 DumpProfileData { source, .. } => source.status_code(),
762
763 InvalidUtf8Value { .. } | InvalidHeaderValue { .. } => StatusCode::InvalidArguments,
764
765 TooManyConcurrentRequests { .. } => StatusCode::RuntimeResourcesExhausted,
766
767 ParsePromQL { source, .. } => source.status_code(),
768 Other { source, .. } => source.status_code(),
769
770 UnexpectedResult { .. } => StatusCode::Unexpected,
771
772 JoinTask { error, .. } => {
773 if error.is_cancelled() {
774 StatusCode::Cancelled
775 } else if error.is_panic() {
776 StatusCode::Unexpected
777 } else {
778 StatusCode::Unknown
779 }
780 }
781
782 #[cfg(feature = "pprof")]
783 DumpPprof { source, .. } => source.status_code(),
784
785 ConvertScalarValue { source, .. } => source.status_code(),
786
787 ToJson { .. } | DataFusion { .. } => StatusCode::Internal,
788
789 ConvertSqlValue { source, .. } => source.status_code(),
790
791 HandleOtelArrowRequest { .. } => StatusCode::Internal,
792
793 Cancelled { .. } => StatusCode::Cancelled,
794
795 Suspended { .. } => StatusCode::Suspended,
796
797 MemoryLimitExceeded { .. } => StatusCode::RateLimited,
798
799 GreptimeProto { source, .. } => source.status_code(),
800 }
801 }
802
803 fn as_any(&self) -> &dyn Any {
804 self
805 }
806}
807
808define_into_tonic_status!(Error);
809
810impl From<std::io::Error> for Error {
811 fn from(e: std::io::Error) -> Self {
812 Error::InternalIo { error: e }
813 }
814}
815
816fn log_error_if_necessary(error: &Error) {
817 if error.status_code().should_log_error() {
818 error!(error; "Failed to handle HTTP request ");
819 } else {
820 warn!(error; "Failed to handle HTTP request ");
821 }
822}
823
824impl IntoResponse for Error {
825 fn into_response(self) -> Response {
826 let error_msg = self.output_msg();
827 let status = status_code_to_http_status(&self.status_code());
828
829 log_error_if_necessary(&self);
830
831 let body = Json(json!({
832 "error": error_msg,
833 }));
834 (status, body).into_response()
835 }
836}
837
838pub fn status_code_to_http_status(status_code: &StatusCode) -> HttpStatusCode {
840 match status_code {
841 StatusCode::Success => HttpStatusCode::OK,
842
843 StatusCode::Cancelled | StatusCode::DeadlineExceeded => HttpStatusCode::GATEWAY_TIMEOUT,
846
847 StatusCode::Unsupported
848 | StatusCode::InvalidArguments
849 | StatusCode::InvalidSyntax
850 | StatusCode::RequestOutdated
851 | StatusCode::RegionAlreadyExists
852 | StatusCode::TableColumnExists
853 | StatusCode::TableAlreadyExists
854 | StatusCode::RegionNotFound
855 | StatusCode::DatabaseNotFound
856 | StatusCode::TableNotFound
857 | StatusCode::TableColumnNotFound
858 | StatusCode::PlanQuery
859 | StatusCode::DatabaseAlreadyExists
860 | StatusCode::TriggerAlreadyExists
861 | StatusCode::TriggerNotFound
862 | StatusCode::FlowNotFound
863 | StatusCode::FlowAlreadyExists => HttpStatusCode::BAD_REQUEST,
864
865 StatusCode::AuthHeaderNotFound
866 | StatusCode::InvalidAuthHeader
867 | StatusCode::UserNotFound
868 | StatusCode::UnsupportedPasswordType
869 | StatusCode::UserPasswordMismatch
870 | StatusCode::RegionReadonly => HttpStatusCode::UNAUTHORIZED,
871
872 StatusCode::PermissionDenied | StatusCode::AccessDenied => HttpStatusCode::FORBIDDEN,
873
874 StatusCode::RateLimited => HttpStatusCode::TOO_MANY_REQUESTS,
875
876 StatusCode::RegionNotReady
877 | StatusCode::TableUnavailable
878 | StatusCode::RegionBusy
879 | StatusCode::StorageUnavailable
880 | StatusCode::External
881 | StatusCode::Suspended => HttpStatusCode::SERVICE_UNAVAILABLE,
882
883 StatusCode::Internal
884 | StatusCode::Unexpected
885 | StatusCode::IllegalState
886 | StatusCode::Unknown
887 | StatusCode::RuntimeResourcesExhausted
888 | StatusCode::EngineExecuteQuery => HttpStatusCode::INTERNAL_SERVER_ERROR,
889 }
890}