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