Skip to main content

common_meta/
error.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::str::Utf8Error;
16use std::sync::Arc;
17
18use common_error::ext::{BoxedError, ErrorExt};
19use common_error::status_code::StatusCode;
20use common_macro::stack_trace_debug;
21use common_procedure::ProcedureId;
22use serde_json::error::Error as JsonError;
23use snafu::{Location, Snafu};
24use store_api::storage::RegionId;
25use table::metadata::TableId;
26
27use crate::DatanodeId;
28use crate::peer::Peer;
29
30#[derive(Snafu)]
31#[snafu(visibility(pub))]
32#[stack_trace_debug]
33pub enum Error {
34    #[snafu(display("Empty key is not allowed"))]
35    EmptyKey {
36        #[snafu(implicit)]
37        location: Location,
38    },
39
40    #[snafu(display(
41        "Another procedure is operating the region: {} on peer: {}",
42        region_id,
43        peer_id
44    ))]
45    RegionOperatingRace {
46        #[snafu(implicit)]
47        location: Location,
48        peer_id: DatanodeId,
49        region_id: RegionId,
50    },
51
52    #[snafu(display("Failed to connect to Etcd"))]
53    ConnectEtcd {
54        #[snafu(source)]
55        error: etcd_client::Error,
56        #[snafu(implicit)]
57        location: Location,
58    },
59
60    #[snafu(display("Failed to execute via Etcd"))]
61    EtcdFailed {
62        #[snafu(source)]
63        error: etcd_client::Error,
64        #[snafu(implicit)]
65        location: Location,
66    },
67
68    #[snafu(display("Failed to execute {} txn operations via Etcd", max_operations))]
69    EtcdTxnFailed {
70        max_operations: usize,
71        #[snafu(source)]
72        error: etcd_client::Error,
73        #[snafu(implicit)]
74        location: Location,
75    },
76
77    #[snafu(display("Failed to get sequence: {}", err_msg))]
78    NextSequence {
79        err_msg: String,
80        #[snafu(implicit)]
81        location: Location,
82    },
83
84    #[snafu(display("Unexpected sequence value: {}", err_msg))]
85    UnexpectedSequenceValue {
86        err_msg: String,
87        #[snafu(implicit)]
88        location: Location,
89    },
90
91    #[snafu(display("Table info not found: {}", table))]
92    TableInfoNotFound {
93        table: String,
94        #[snafu(implicit)]
95        location: Location,
96    },
97
98    #[snafu(display("Failed to register procedure loader, type name: {}", type_name))]
99    RegisterProcedureLoader {
100        type_name: String,
101        #[snafu(implicit)]
102        location: Location,
103        source: common_procedure::error::Error,
104    },
105
106    #[snafu(display("Failed to register repartition procedure loader"))]
107    RegisterRepartitionProcedureLoader {
108        #[snafu(implicit)]
109        location: Location,
110        source: BoxedError,
111    },
112
113    #[snafu(display("Failed to create repartition procedure"))]
114    CreateRepartitionProcedure {
115        source: BoxedError,
116        #[snafu(implicit)]
117        location: Location,
118    },
119
120    #[snafu(display("Failed to submit procedure"))]
121    SubmitProcedure {
122        #[snafu(implicit)]
123        location: Location,
124        source: common_procedure::Error,
125    },
126
127    #[snafu(display("Failed to query procedure"))]
128    QueryProcedure {
129        #[snafu(implicit)]
130        location: Location,
131        source: common_procedure::Error,
132    },
133
134    #[snafu(display("Procedure not found: {pid}"))]
135    ProcedureNotFound {
136        #[snafu(implicit)]
137        location: Location,
138        pid: String,
139    },
140
141    #[snafu(display("Failed to parse procedure id: {key}"))]
142    ParseProcedureId {
143        #[snafu(implicit)]
144        location: Location,
145        key: String,
146        #[snafu(source)]
147        error: common_procedure::ParseIdError,
148    },
149
150    #[snafu(display("Unsupported operation {}", operation))]
151    Unsupported {
152        operation: String,
153        #[snafu(implicit)]
154        location: Location,
155    },
156
157    #[snafu(display("Trying to write to a read-only kv backend: {}", name))]
158    ReadOnlyKvBackend {
159        name: String,
160        #[snafu(implicit)]
161        location: Location,
162    },
163
164    #[snafu(display("Failed to get procedure state receiver, procedure id: {procedure_id}"))]
165    ProcedureStateReceiver {
166        procedure_id: ProcedureId,
167        #[snafu(implicit)]
168        location: Location,
169        source: common_procedure::Error,
170    },
171
172    #[snafu(display("Procedure state receiver not found: {procedure_id}"))]
173    ProcedureStateReceiverNotFound {
174        procedure_id: ProcedureId,
175        #[snafu(implicit)]
176        location: Location,
177    },
178
179    #[snafu(display("Failed to wait procedure done"))]
180    WaitProcedure {
181        #[snafu(implicit)]
182        location: Location,
183        source: common_procedure::Error,
184    },
185
186    #[snafu(display("Failed to start procedure manager"))]
187    StartProcedureManager {
188        #[snafu(implicit)]
189        location: Location,
190        source: common_procedure::Error,
191    },
192
193    #[snafu(display("Failed to stop procedure manager"))]
194    StopProcedureManager {
195        #[snafu(implicit)]
196        location: Location,
197        source: common_procedure::Error,
198    },
199
200    #[snafu(display(
201        "Failed to get procedure output, procedure id: {procedure_id}, error: {err_msg}"
202    ))]
203    ProcedureOutput {
204        procedure_id: String,
205        err_msg: String,
206        #[snafu(implicit)]
207        location: Location,
208    },
209
210    #[snafu(display("Primary key '{key}' not found when creating region request"))]
211    PrimaryKeyNotFound {
212        key: String,
213        #[snafu(implicit)]
214        location: Location,
215    },
216
217    #[snafu(display("Failed to build table meta for table: {}", table_name))]
218    BuildTableMeta {
219        table_name: String,
220        #[snafu(source)]
221        error: table::metadata::TableMetaBuilderError,
222        #[snafu(implicit)]
223        location: Location,
224    },
225
226    #[snafu(display("Table occurs error"))]
227    Table {
228        #[snafu(implicit)]
229        location: Location,
230        source: table::error::Error,
231    },
232
233    #[snafu(display("Failed to find table route for table id {}", table_id))]
234    TableRouteNotFound {
235        table_id: TableId,
236        #[snafu(implicit)]
237        location: Location,
238    },
239
240    #[snafu(display("Failed to find table repartition metadata for table id {}", table_id))]
241    TableRepartNotFound {
242        table_id: TableId,
243        #[snafu(implicit)]
244        location: Location,
245    },
246
247    #[snafu(display("Failed to decode protobuf"))]
248    DecodeProto {
249        #[snafu(implicit)]
250        location: Location,
251        #[snafu(source)]
252        error: prost::DecodeError,
253    },
254
255    #[snafu(display("Failed to encode object into json"))]
256    EncodeJson {
257        #[snafu(implicit)]
258        location: Location,
259        #[snafu(source)]
260        error: JsonError,
261    },
262
263    #[snafu(display("Failed to decode object from json"))]
264    DecodeJson {
265        #[snafu(implicit)]
266        location: Location,
267        #[snafu(source)]
268        error: JsonError,
269    },
270
271    #[snafu(display("Failed to serialize to json: {}", input))]
272    SerializeToJson {
273        input: String,
274        #[snafu(source)]
275        error: serde_json::error::Error,
276        #[snafu(implicit)]
277        location: Location,
278    },
279
280    #[snafu(display("Failed to deserialize from json: {}", input))]
281    DeserializeFromJson {
282        input: String,
283        #[snafu(source)]
284        error: serde_json::error::Error,
285        #[snafu(implicit)]
286        location: Location,
287    },
288
289    #[snafu(display("Payload not exist"))]
290    PayloadNotExist {
291        #[snafu(implicit)]
292        location: Location,
293    },
294
295    #[snafu(display("Failed to serde json"))]
296    SerdeJson {
297        #[snafu(source)]
298        error: serde_json::error::Error,
299        #[snafu(implicit)]
300        location: Location,
301    },
302
303    #[snafu(display("Failed to parse value {} into key {}", value, key))]
304    ParseOption {
305        key: String,
306        value: String,
307        #[snafu(implicit)]
308        location: Location,
309    },
310
311    #[snafu(display("Corrupted table route data, err: {}", err_msg))]
312    RouteInfoCorrupted {
313        err_msg: String,
314        #[snafu(implicit)]
315        location: Location,
316    },
317
318    #[snafu(display("Illegal state from server, code: {}, error: {}", code, err_msg))]
319    IllegalServerState {
320        code: i32,
321        err_msg: String,
322        #[snafu(implicit)]
323        location: Location,
324    },
325
326    #[snafu(display("Failed to convert alter table request"))]
327    ConvertAlterTableRequest {
328        source: common_grpc_expr::error::Error,
329        #[snafu(implicit)]
330        location: Location,
331    },
332
333    #[snafu(display("Invalid protobuf message: {err_msg}"))]
334    InvalidProtoMsg {
335        err_msg: String,
336        #[snafu(implicit)]
337        location: Location,
338    },
339
340    #[snafu(display("Unexpected: {err_msg}"))]
341    Unexpected {
342        err_msg: String,
343        #[snafu(implicit)]
344        location: Location,
345    },
346
347    #[snafu(display("Metasrv election has no leader at this moment"))]
348    ElectionNoLeader {
349        #[snafu(implicit)]
350        location: Location,
351    },
352
353    #[snafu(display("Metasrv election leader lease expired"))]
354    ElectionLeaderLeaseExpired {
355        #[snafu(implicit)]
356        location: Location,
357    },
358
359    #[snafu(display("Metasrv election leader lease changed during election"))]
360    ElectionLeaderLeaseChanged {
361        #[snafu(implicit)]
362        location: Location,
363    },
364
365    #[snafu(display("Table already exists, table: {}", table_name))]
366    TableAlreadyExists {
367        table_name: String,
368        #[snafu(implicit)]
369        location: Location,
370    },
371
372    #[snafu(display("View already exists, view: {}", view_name))]
373    ViewAlreadyExists {
374        view_name: String,
375        #[snafu(implicit)]
376        location: Location,
377    },
378
379    #[snafu(display("Flow already exists: {}", flow_name))]
380    FlowAlreadyExists {
381        flow_name: String,
382        #[snafu(implicit)]
383        location: Location,
384    },
385
386    #[snafu(display("Schema already exists, catalog:{}, schema: {}", catalog, schema))]
387    SchemaAlreadyExists {
388        catalog: String,
389        schema: String,
390        #[snafu(implicit)]
391        location: Location,
392    },
393
394    #[snafu(display("Failed to convert raw key to str"))]
395    ConvertRawKey {
396        #[snafu(implicit)]
397        location: Location,
398        #[snafu(source)]
399        error: Utf8Error,
400    },
401
402    #[snafu(display("Table not found: '{}'", table_name))]
403    TableNotFound {
404        table_name: String,
405        #[snafu(implicit)]
406        location: Location,
407    },
408
409    #[snafu(display("Region not found: {}", region_id))]
410    RegionNotFound {
411        region_id: RegionId,
412        #[snafu(implicit)]
413        location: Location,
414    },
415
416    #[snafu(display("View not found: '{}'", view_name))]
417    ViewNotFound {
418        view_name: String,
419        #[snafu(implicit)]
420        location: Location,
421    },
422
423    #[snafu(display("Flow not found: '{}'", flow_name))]
424    FlowNotFound {
425        flow_name: String,
426        #[snafu(implicit)]
427        location: Location,
428    },
429
430    #[snafu(display("Flow route not found: '{}'", flow_name))]
431    FlowRouteNotFound {
432        flow_name: String,
433        #[snafu(implicit)]
434        location: Location,
435    },
436
437    #[snafu(display("Schema nod found, schema: {}", table_schema))]
438    SchemaNotFound {
439        table_schema: String,
440        #[snafu(implicit)]
441        location: Location,
442    },
443
444    #[snafu(display("Catalog not found, catalog: {}", catalog))]
445    CatalogNotFound {
446        catalog: String,
447        #[snafu(implicit)]
448        location: Location,
449    },
450
451    #[snafu(display("Invalid metadata, err: {}", err_msg))]
452    InvalidMetadata {
453        err_msg: String,
454        #[snafu(implicit)]
455        location: Location,
456    },
457
458    #[snafu(display("Invalid view info, err: {}", err_msg))]
459    InvalidViewInfo {
460        err_msg: String,
461        #[snafu(implicit)]
462        location: Location,
463    },
464
465    #[snafu(display("Invalid flow request body: {:?}", body))]
466    InvalidFlowRequestBody {
467        body: Box<Option<api::v1::flow::flow_request::Body>>,
468        #[snafu(implicit)]
469        location: Location,
470    },
471
472    #[snafu(display("Failed to get kv cache, err: {}", err_msg))]
473    GetKvCache { err_msg: String },
474
475    #[snafu(display("Get null from cache, key: {}", key))]
476    CacheNotGet {
477        key: String,
478        #[snafu(implicit)]
479        location: Location,
480    },
481
482    #[snafu(display("Etcd txn error: {err_msg}"))]
483    EtcdTxnOpResponse {
484        err_msg: String,
485        #[snafu(implicit)]
486        location: Location,
487    },
488
489    #[snafu(display("External error"))]
490    External {
491        #[snafu(implicit)]
492        location: Location,
493        source: BoxedError,
494    },
495
496    #[snafu(display("The response exceeded size limit"))]
497    ResponseExceededSizeLimit {
498        #[snafu(implicit)]
499        location: Location,
500        source: BoxedError,
501    },
502
503    #[snafu(display("Invalid heartbeat response"))]
504    InvalidHeartbeatResponse {
505        #[snafu(implicit)]
506        location: Location,
507    },
508
509    #[snafu(display("Failed to operate on datanode: {}", peer))]
510    OperateDatanode {
511        #[snafu(implicit)]
512        location: Location,
513        peer: Peer,
514        source: BoxedError,
515    },
516
517    #[snafu(display("Retry later"))]
518    RetryLater {
519        source: BoxedError,
520        clean_poisons: bool,
521    },
522
523    #[snafu(display("Abort procedure"))]
524    AbortProcedure {
525        #[snafu(implicit)]
526        location: Location,
527        source: BoxedError,
528        clean_poisons: bool,
529    },
530
531    #[snafu(display("Failed to serialize WAL options for region: {region_id}"))]
532    SerializeWalOptions {
533        region_id: RegionId,
534        #[snafu(source)]
535        error: serde_json::Error,
536        #[snafu(implicit)]
537        location: Location,
538    },
539
540    #[snafu(display("Invalid number of topics {}", num_topics))]
541    InvalidNumTopics {
542        num_topics: usize,
543        #[snafu(implicit)]
544        location: Location,
545    },
546
547    #[snafu(display(
548        "Failed to build a Kafka client, broker endpoints: {:?}",
549        broker_endpoints
550    ))]
551    BuildKafkaClient {
552        broker_endpoints: Vec<String>,
553        #[snafu(implicit)]
554        location: Location,
555        #[snafu(source)]
556        error: rskafka::client::error::Error,
557    },
558
559    #[snafu(display("Failed to create TLS Config"))]
560    TlsConfig {
561        #[snafu(implicit)]
562        location: Location,
563        source: common_wal::error::Error,
564    },
565
566    #[snafu(display("Failed to build a Kafka controller client"))]
567    BuildKafkaCtrlClient {
568        #[snafu(implicit)]
569        location: Location,
570        #[snafu(source)]
571        error: rskafka::client::error::Error,
572    },
573
574    #[snafu(display(
575        "Failed to get a Kafka partition client, topic: {}, partition: {}",
576        topic,
577        partition
578    ))]
579    KafkaPartitionClient {
580        topic: String,
581        partition: i32,
582        #[snafu(implicit)]
583        location: Location,
584        #[snafu(source)]
585        error: rskafka::client::error::Error,
586    },
587
588    #[snafu(display(
589        "Failed to get offset from Kafka, topic: {}, partition: {}",
590        topic,
591        partition
592    ))]
593    KafkaGetOffset {
594        topic: String,
595        partition: i32,
596        #[snafu(implicit)]
597        location: Location,
598        #[snafu(source)]
599        error: rskafka::client::error::Error,
600    },
601
602    #[snafu(display("Failed to produce records to Kafka, topic: {}", topic))]
603    ProduceRecord {
604        topic: String,
605        #[snafu(implicit)]
606        location: Location,
607        #[snafu(source)]
608        error: rskafka::client::error::Error,
609    },
610
611    #[snafu(display("Failed to create a Kafka wal topic"))]
612    CreateKafkaWalTopic {
613        #[snafu(implicit)]
614        location: Location,
615        #[snafu(source)]
616        error: rskafka::client::error::Error,
617    },
618
619    #[snafu(display("The topic pool is empty"))]
620    EmptyTopicPool {
621        #[snafu(implicit)]
622        location: Location,
623    },
624
625    #[snafu(display("Unexpected table route type: {}", err_msg))]
626    UnexpectedLogicalRouteTable {
627        #[snafu(implicit)]
628        location: Location,
629        err_msg: String,
630    },
631
632    #[snafu(display("The tasks of {} cannot be empty", name))]
633    EmptyDdlTasks {
634        name: String,
635        #[snafu(implicit)]
636        location: Location,
637    },
638
639    #[snafu(display("Metadata corruption: {}", err_msg))]
640    MetadataCorruption {
641        err_msg: String,
642        #[snafu(implicit)]
643        location: Location,
644    },
645
646    #[snafu(display("Alter logical tables invalid arguments: {}", err_msg))]
647    AlterLogicalTablesInvalidArguments {
648        err_msg: String,
649        #[snafu(implicit)]
650        location: Location,
651    },
652
653    #[snafu(display("Create logical tables invalid arguments: {}", err_msg))]
654    CreateLogicalTablesInvalidArguments {
655        err_msg: String,
656        #[snafu(implicit)]
657        location: Location,
658    },
659
660    #[snafu(display("Invalid node info key: {}", key))]
661    InvalidNodeInfoKey {
662        key: String,
663        #[snafu(implicit)]
664        location: Location,
665    },
666
667    #[snafu(display("Invalid node stat key: {}", key))]
668    InvalidStatKey {
669        key: String,
670        #[snafu(implicit)]
671        location: Location,
672    },
673
674    #[snafu(display("Failed to parse number: {}", err_msg))]
675    ParseNum {
676        err_msg: String,
677        #[snafu(source)]
678        error: std::num::ParseIntError,
679        #[snafu(implicit)]
680        location: Location,
681    },
682
683    #[snafu(display("Invalid role: {}", role))]
684    InvalidRole {
685        role: i32,
686        #[snafu(implicit)]
687        location: Location,
688    },
689
690    #[snafu(display("Invalid set database option, key: {}, value: {}", key, value))]
691    InvalidSetDatabaseOption {
692        key: String,
693        value: String,
694        #[snafu(implicit)]
695        location: Location,
696    },
697
698    #[snafu(display("Invalid unset database option, key: {}", key))]
699    InvalidUnsetDatabaseOption {
700        key: String,
701        #[snafu(implicit)]
702        location: Location,
703    },
704
705    #[snafu(display("Invalid prefix: {}, key: {}", prefix, key))]
706    MismatchPrefix {
707        prefix: String,
708        key: String,
709        #[snafu(implicit)]
710        location: Location,
711    },
712
713    #[snafu(display("Failed to move values: {err_msg}"))]
714    MoveValues {
715        err_msg: String,
716        #[snafu(implicit)]
717        location: Location,
718    },
719
720    #[snafu(display("Failed to parse {} from utf8", name))]
721    FromUtf8 {
722        name: String,
723        #[snafu(source)]
724        error: std::string::FromUtf8Error,
725        #[snafu(implicit)]
726        location: Location,
727    },
728
729    #[snafu(display("Value not exists"))]
730    ValueNotExist {
731        #[snafu(implicit)]
732        location: Location,
733    },
734
735    #[snafu(display("Failed to get cache"))]
736    GetCache { source: Arc<Error> },
737
738    #[snafu(display(
739        "Failed to get latest cache value after {} attempts due to concurrent invalidation",
740        attempts
741    ))]
742    GetLatestCacheRetryExceeded {
743        attempts: usize,
744        #[snafu(implicit)]
745        location: Location,
746    },
747
748    #[cfg(feature = "pg_kvbackend")]
749    #[snafu(display("Failed to execute via Postgres, sql: {}", sql))]
750    PostgresExecution {
751        sql: String,
752        #[snafu(source)]
753        error: tokio_postgres::Error,
754        #[snafu(implicit)]
755        location: Location,
756    },
757
758    #[cfg(feature = "pg_kvbackend")]
759    #[snafu(display("Failed to create connection pool for Postgres"))]
760    CreatePostgresPool {
761        #[snafu(source)]
762        error: deadpool_postgres::CreatePoolError,
763        #[snafu(implicit)]
764        location: Location,
765    },
766
767    #[cfg(feature = "pg_kvbackend")]
768    #[snafu(display("Failed to get Postgres connection from pool: {}", reason))]
769    GetPostgresConnection {
770        reason: String,
771        #[snafu(implicit)]
772        location: Location,
773    },
774
775    #[cfg(feature = "pg_kvbackend")]
776    #[snafu(display("Failed to get Postgres client"))]
777    GetPostgresClient {
778        #[snafu(source)]
779        error: deadpool::managed::PoolError<tokio_postgres::Error>,
780        #[snafu(implicit)]
781        location: Location,
782    },
783
784    #[cfg(feature = "pg_kvbackend")]
785    #[snafu(display("Failed to {} Postgres transaction", operation))]
786    PostgresTransaction {
787        #[snafu(source)]
788        error: tokio_postgres::Error,
789        #[snafu(implicit)]
790        location: Location,
791        operation: String,
792    },
793
794    #[cfg(feature = "pg_kvbackend")]
795    #[snafu(display("Failed to setup PostgreSQL TLS configuration: {}", reason))]
796    PostgresTlsConfig {
797        reason: String,
798        #[snafu(implicit)]
799        location: Location,
800    },
801
802    #[snafu(display("Failed to load TLS certificate from path: {}", path))]
803    LoadTlsCertificate {
804        path: String,
805        #[snafu(source)]
806        error: std::io::Error,
807        #[snafu(implicit)]
808        location: Location,
809    },
810
811    #[cfg(feature = "pg_kvbackend")]
812    #[snafu(display("Invalid TLS configuration: {}", reason))]
813    InvalidTlsConfig {
814        reason: String,
815        #[snafu(implicit)]
816        location: Location,
817    },
818
819    #[cfg(feature = "mysql_kvbackend")]
820    #[snafu(display("Failed to execute via MySql, sql: {}", sql))]
821    MySqlExecution {
822        sql: String,
823        #[snafu(source)]
824        error: sqlx::Error,
825        #[snafu(implicit)]
826        location: Location,
827    },
828
829    #[cfg(feature = "mysql_kvbackend")]
830    #[snafu(display("Failed to create connection pool for MySql"))]
831    CreateMySqlPool {
832        #[snafu(source)]
833        error: sqlx::Error,
834        #[snafu(implicit)]
835        location: Location,
836    },
837
838    #[cfg(feature = "mysql_kvbackend")]
839    #[snafu(display("Failed to decode sql value"))]
840    DecodeSqlValue {
841        #[snafu(source)]
842        error: sqlx::error::Error,
843        #[snafu(implicit)]
844        location: Location,
845    },
846
847    #[cfg(feature = "mysql_kvbackend")]
848    #[snafu(display("Failed to acquire mysql client from pool"))]
849    AcquireMySqlClient {
850        #[snafu(source)]
851        error: sqlx::Error,
852        #[snafu(implicit)]
853        location: Location,
854    },
855
856    #[cfg(feature = "mysql_kvbackend")]
857    #[snafu(display("Failed to {} MySql transaction", operation))]
858    MySqlTransaction {
859        #[snafu(source)]
860        error: sqlx::Error,
861        #[snafu(implicit)]
862        location: Location,
863        operation: String,
864    },
865
866    #[cfg(any(feature = "pg_kvbackend", feature = "mysql_kvbackend"))]
867    #[snafu(display("Rds transaction retry failed"))]
868    RdsTransactionRetryFailed {
869        #[snafu(implicit)]
870        location: Location,
871    },
872
873    #[cfg(any(feature = "pg_kvbackend", feature = "mysql_kvbackend"))]
874    #[snafu(display("Sql execution timeout, sql: {}, duration: {:?}", sql, duration))]
875    SqlExecutionTimeout {
876        sql: String,
877        duration: std::time::Duration,
878        #[snafu(implicit)]
879        location: Location,
880    },
881
882    #[snafu(display(
883        "Datanode table info not found, table id: {}, datanode id: {}",
884        table_id,
885        datanode_id
886    ))]
887    DatanodeTableInfoNotFound {
888        datanode_id: DatanodeId,
889        table_id: TableId,
890        #[snafu(implicit)]
891        location: Location,
892    },
893
894    #[snafu(display("Invalid topic name prefix: {}", prefix))]
895    InvalidTopicNamePrefix {
896        prefix: String,
897        #[snafu(implicit)]
898        location: Location,
899    },
900
901    #[snafu(display("No leader found for table_id: {}", table_id))]
902    NoLeader {
903        table_id: TableId,
904        #[snafu(implicit)]
905        location: Location,
906    },
907
908    #[snafu(display(
909        "Procedure poison key already exists with a different value, key: {}, value: {}",
910        key,
911        value
912    ))]
913    ProcedurePoisonConflict {
914        key: String,
915        value: String,
916        #[snafu(implicit)]
917        location: Location,
918    },
919
920    #[snafu(display("Failed to put poison, table metadata may be corrupted"))]
921    PutPoison {
922        #[snafu(implicit)]
923        location: Location,
924        #[snafu(source)]
925        source: common_procedure::error::Error,
926    },
927
928    #[snafu(display("Invalid file path: {}", file_path))]
929    InvalidFilePath {
930        #[snafu(implicit)]
931        location: Location,
932        file_path: String,
933    },
934
935    #[snafu(display("Failed to serialize flexbuffers"))]
936    SerializeFlexbuffers {
937        #[snafu(implicit)]
938        location: Location,
939        #[snafu(source)]
940        error: flexbuffers::SerializationError,
941    },
942
943    #[snafu(display("Failed to deserialize flexbuffers"))]
944    DeserializeFlexbuffers {
945        #[snafu(implicit)]
946        location: Location,
947        #[snafu(source)]
948        error: flexbuffers::DeserializationError,
949    },
950
951    #[snafu(display("Failed to read flexbuffers"))]
952    ReadFlexbuffers {
953        #[snafu(implicit)]
954        location: Location,
955        #[snafu(source)]
956        error: flexbuffers::ReaderError,
957    },
958
959    #[snafu(display("Invalid file name: {}", reason))]
960    InvalidFileName {
961        #[snafu(implicit)]
962        location: Location,
963        reason: String,
964    },
965
966    #[snafu(display("Invalid file extension: {}", reason))]
967    InvalidFileExtension {
968        #[snafu(implicit)]
969        location: Location,
970        reason: String,
971    },
972
973    #[snafu(display("Failed to write object, file path: {}", file_path))]
974    WriteObject {
975        #[snafu(implicit)]
976        location: Location,
977        file_path: String,
978        #[snafu(source)]
979        error: object_store::Error,
980    },
981
982    #[snafu(display("Failed to read object, file path: {}", file_path))]
983    ReadObject {
984        #[snafu(implicit)]
985        location: Location,
986        file_path: String,
987        #[snafu(source)]
988        error: object_store::Error,
989    },
990
991    #[snafu(display("Missing column ids"))]
992    MissingColumnIds {
993        #[snafu(implicit)]
994        location: Location,
995    },
996
997    #[snafu(display(
998        "Missing column in column metadata: {}, table: {}, table_id: {}",
999        column_name,
1000        table_name,
1001        table_id,
1002    ))]
1003    MissingColumnInColumnMetadata {
1004        column_name: String,
1005        #[snafu(implicit)]
1006        location: Location,
1007        table_name: String,
1008        table_id: TableId,
1009    },
1010
1011    #[snafu(display(
1012        "Mismatch column id: column_name: {}, column_id: {}, table: {}, table_id: {}",
1013        column_name,
1014        column_id,
1015        table_name,
1016        table_id,
1017    ))]
1018    MismatchColumnId {
1019        column_name: String,
1020        column_id: u32,
1021        #[snafu(implicit)]
1022        location: Location,
1023        table_name: String,
1024        table_id: TableId,
1025    },
1026
1027    #[snafu(display("Failed to convert column def, column: {}", column))]
1028    ConvertColumnDef {
1029        column: String,
1030        #[snafu(implicit)]
1031        location: Location,
1032        source: api::error::Error,
1033    },
1034
1035    #[snafu(display("Failed to convert time ranges"))]
1036    ConvertTimeRanges {
1037        #[snafu(implicit)]
1038        location: Location,
1039        source: api::error::Error,
1040    },
1041
1042    #[snafu(display(
1043        "Column metadata inconsistencies found in table: {}, table_id: {}",
1044        table_name,
1045        table_id
1046    ))]
1047    ColumnMetadataConflicts {
1048        table_name: String,
1049        table_id: TableId,
1050    },
1051
1052    #[snafu(display(
1053        "Column not found in column metadata, column_name: {}, column_id: {}",
1054        column_name,
1055        column_id
1056    ))]
1057    ColumnNotFound { column_name: String, column_id: u32 },
1058
1059    #[snafu(display(
1060        "Column id mismatch, column_name: {}, expected column_id: {}, actual column_id: {}",
1061        column_name,
1062        expected_column_id,
1063        actual_column_id
1064    ))]
1065    ColumnIdMismatch {
1066        column_name: String,
1067        expected_column_id: u32,
1068        actual_column_id: u32,
1069    },
1070
1071    #[snafu(display(
1072        "Timestamp column mismatch, expected column_name: {}, expected column_id: {}, actual column_name: {}, actual column_id: {}",
1073        expected_column_name,
1074        expected_column_id,
1075        actual_column_name,
1076        actual_column_id,
1077    ))]
1078    TimestampMismatch {
1079        expected_column_name: String,
1080        expected_column_id: u32,
1081        actual_column_name: String,
1082        actual_column_id: u32,
1083    },
1084
1085    #[cfg(feature = "enterprise")]
1086    #[snafu(display("Too large duration"))]
1087    TooLargeDuration {
1088        #[snafu(source)]
1089        error: prost_types::DurationError,
1090        #[snafu(implicit)]
1091        location: Location,
1092    },
1093
1094    #[cfg(feature = "enterprise")]
1095    #[snafu(display("Negative duration"))]
1096    NegativeDuration {
1097        #[snafu(source)]
1098        error: prost_types::DurationError,
1099        #[snafu(implicit)]
1100        location: Location,
1101    },
1102
1103    #[cfg(feature = "enterprise")]
1104    #[snafu(display("Missing interval field"))]
1105    MissingInterval {
1106        #[snafu(implicit)]
1107        location: Location,
1108    },
1109}
1110
1111pub type Result<T> = std::result::Result<T, Error>;
1112
1113impl ErrorExt for Error {
1114    fn status_code(&self) -> StatusCode {
1115        use Error::*;
1116        match self {
1117            IllegalServerState { .. }
1118            | EtcdTxnOpResponse { .. }
1119            | EtcdFailed { .. }
1120            | EtcdTxnFailed { .. }
1121            | ConnectEtcd { .. }
1122            | MoveValues { .. }
1123            | GetCache { .. }
1124            | GetLatestCacheRetryExceeded { .. }
1125            | SerializeToJson { .. }
1126            | DeserializeFromJson { .. }
1127            | ElectionNoLeader { .. }
1128            | ElectionLeaderLeaseExpired { .. }
1129            | ElectionLeaderLeaseChanged { .. } => StatusCode::Internal,
1130
1131            NoLeader { .. } => StatusCode::TableUnavailable,
1132            ValueNotExist { .. }
1133            | ProcedurePoisonConflict { .. }
1134            | ProcedureStateReceiverNotFound { .. }
1135            | MissingColumnIds { .. }
1136            | MissingColumnInColumnMetadata { .. }
1137            | MismatchColumnId { .. }
1138            | ColumnMetadataConflicts { .. }
1139            | ColumnNotFound { .. }
1140            | ColumnIdMismatch { .. }
1141            | TimestampMismatch { .. } => StatusCode::Unexpected,
1142
1143            Unsupported { .. } | ReadOnlyKvBackend { .. } => StatusCode::Unsupported,
1144            WriteObject { .. } | ReadObject { .. } => StatusCode::StorageUnavailable,
1145
1146            SerdeJson { .. }
1147            | ParseOption { .. }
1148            | RouteInfoCorrupted { .. }
1149            | InvalidProtoMsg { .. }
1150            | InvalidMetadata { .. }
1151            | Unexpected { .. }
1152            | TableInfoNotFound { .. }
1153            | NextSequence { .. }
1154            | UnexpectedSequenceValue { .. }
1155            | InvalidHeartbeatResponse { .. }
1156            | EncodeJson { .. }
1157            | DecodeJson { .. }
1158            | PayloadNotExist { .. }
1159            | ConvertRawKey { .. }
1160            | DecodeProto { .. }
1161            | BuildTableMeta { .. }
1162            | TableRouteNotFound { .. }
1163            | TableRepartNotFound { .. }
1164            | RegionOperatingRace { .. }
1165            | SerializeWalOptions { .. }
1166            | BuildKafkaClient { .. }
1167            | BuildKafkaCtrlClient { .. }
1168            | KafkaPartitionClient { .. }
1169            | ProduceRecord { .. }
1170            | CreateKafkaWalTopic { .. }
1171            | EmptyTopicPool { .. }
1172            | UnexpectedLogicalRouteTable { .. }
1173            | ProcedureOutput { .. }
1174            | FromUtf8 { .. }
1175            | MetadataCorruption { .. }
1176            | KafkaGetOffset { .. }
1177            | ReadFlexbuffers { .. }
1178            | SerializeFlexbuffers { .. }
1179            | DeserializeFlexbuffers { .. }
1180            | ConvertTimeRanges { .. } => StatusCode::Unexpected,
1181
1182            GetKvCache { .. } | CacheNotGet { .. } => StatusCode::Internal,
1183
1184            SchemaAlreadyExists { .. } => StatusCode::DatabaseAlreadyExists,
1185
1186            ProcedureNotFound { .. }
1187            | InvalidViewInfo { .. }
1188            | PrimaryKeyNotFound { .. }
1189            | EmptyKey { .. }
1190            | AlterLogicalTablesInvalidArguments { .. }
1191            | CreateLogicalTablesInvalidArguments { .. }
1192            | MismatchPrefix { .. }
1193            | TlsConfig { .. }
1194            | InvalidSetDatabaseOption { .. }
1195            | InvalidUnsetDatabaseOption { .. }
1196            | InvalidTopicNamePrefix { .. }
1197            | InvalidFileExtension { .. }
1198            | InvalidFileName { .. }
1199            | InvalidFlowRequestBody { .. }
1200            | InvalidFilePath { .. } => StatusCode::InvalidArguments,
1201
1202            #[cfg(feature = "enterprise")]
1203            MissingInterval { .. } | NegativeDuration { .. } | TooLargeDuration { .. } => {
1204                StatusCode::InvalidArguments
1205            }
1206
1207            FlowNotFound { .. } => StatusCode::FlowNotFound,
1208            FlowRouteNotFound { .. } => StatusCode::Unexpected,
1209            FlowAlreadyExists { .. } => StatusCode::FlowAlreadyExists,
1210
1211            ViewNotFound { .. } | TableNotFound { .. } | RegionNotFound { .. } => {
1212                StatusCode::TableNotFound
1213            }
1214            ViewAlreadyExists { .. } | TableAlreadyExists { .. } => StatusCode::TableAlreadyExists,
1215
1216            SubmitProcedure { source, .. }
1217            | QueryProcedure { source, .. }
1218            | WaitProcedure { source, .. }
1219            | StartProcedureManager { source, .. }
1220            | StopProcedureManager { source, .. } => source.status_code(),
1221            RegisterProcedureLoader { source, .. } => source.status_code(),
1222            External { source, .. } => source.status_code(),
1223            ResponseExceededSizeLimit { source, .. } => source.status_code(),
1224            OperateDatanode { source, .. } => source.status_code(),
1225            Table { source, .. } => source.status_code(),
1226            RetryLater { source, .. } => source.status_code(),
1227            AbortProcedure { source, .. } => source.status_code(),
1228            ConvertAlterTableRequest { source, .. } => source.status_code(),
1229            PutPoison { source, .. } => source.status_code(),
1230            ConvertColumnDef { source, .. } => source.status_code(),
1231            ProcedureStateReceiver { source, .. } => source.status_code(),
1232            RegisterRepartitionProcedureLoader { source, .. } => source.status_code(),
1233            CreateRepartitionProcedure { source, .. } => source.status_code(),
1234
1235            ParseProcedureId { .. }
1236            | InvalidNumTopics { .. }
1237            | SchemaNotFound { .. }
1238            | CatalogNotFound { .. }
1239            | InvalidNodeInfoKey { .. }
1240            | InvalidStatKey { .. }
1241            | ParseNum { .. }
1242            | InvalidRole { .. }
1243            | EmptyDdlTasks { .. } => StatusCode::InvalidArguments,
1244
1245            LoadTlsCertificate { .. } => StatusCode::Internal,
1246
1247            #[cfg(feature = "pg_kvbackend")]
1248            PostgresExecution { .. }
1249            | CreatePostgresPool { .. }
1250            | GetPostgresConnection { .. }
1251            | GetPostgresClient { .. }
1252            | PostgresTransaction { .. }
1253            | PostgresTlsConfig { .. }
1254            | InvalidTlsConfig { .. } => StatusCode::Internal,
1255            #[cfg(feature = "mysql_kvbackend")]
1256            MySqlExecution { .. }
1257            | CreateMySqlPool { .. }
1258            | DecodeSqlValue { .. }
1259            | AcquireMySqlClient { .. }
1260            | MySqlTransaction { .. } => StatusCode::Internal,
1261            #[cfg(any(feature = "pg_kvbackend", feature = "mysql_kvbackend"))]
1262            RdsTransactionRetryFailed { .. } | SqlExecutionTimeout { .. } => StatusCode::Internal,
1263            DatanodeTableInfoNotFound { .. } => StatusCode::Internal,
1264        }
1265    }
1266
1267    fn as_any(&self) -> &dyn std::any::Any {
1268        self
1269    }
1270}
1271
1272impl Error {
1273    #[cfg(any(feature = "pg_kvbackend", feature = "mysql_kvbackend"))]
1274    /// Check if the error is a serialization error.
1275    pub fn is_serialization_error(&self) -> bool {
1276        match self {
1277            #[cfg(feature = "pg_kvbackend")]
1278            Error::PostgresTransaction { error, .. } => {
1279                error.code() == Some(&tokio_postgres::error::SqlState::T_R_SERIALIZATION_FAILURE)
1280            }
1281            #[cfg(feature = "pg_kvbackend")]
1282            Error::PostgresExecution { error, .. } => {
1283                error.code() == Some(&tokio_postgres::error::SqlState::T_R_SERIALIZATION_FAILURE)
1284            }
1285            #[cfg(feature = "mysql_kvbackend")]
1286            Error::MySqlExecution {
1287                error: sqlx::Error::Database(database_error),
1288                ..
1289            } => {
1290                matches!(
1291                    database_error.message(),
1292                    "Deadlock found when trying to get lock; try restarting transaction"
1293                        | "can't serialize access for this transaction"
1294                )
1295            }
1296            _ => false,
1297        }
1298    }
1299
1300    /// Creates a new [Error::RetryLater] error from source `err`.
1301    pub fn retry_later<E: ErrorExt + Send + Sync + 'static>(err: E) -> Error {
1302        Error::RetryLater {
1303            source: BoxedError::new(err),
1304            clean_poisons: false,
1305        }
1306    }
1307
1308    /// Determine whether it is a retry later type through [StatusCode]
1309    pub fn is_retry_later(&self) -> bool {
1310        matches!(
1311            self,
1312            Error::RetryLater { .. } | Error::GetLatestCacheRetryExceeded { .. }
1313        )
1314    }
1315
1316    /// Determine whether it needs to clean poisons.
1317    pub fn need_clean_poisons(&self) -> bool {
1318        matches!(
1319            self,
1320            Error::AbortProcedure { clean_poisons, .. } if *clean_poisons
1321        ) || matches!(
1322            self,
1323            Error::RetryLater { clean_poisons, .. } if *clean_poisons
1324        )
1325    }
1326
1327    /// Returns true if the response exceeds the size limit.
1328    pub fn is_exceeded_size_limit(&self) -> bool {
1329        match self {
1330            Error::EtcdFailed {
1331                error: etcd_client::Error::GRpcStatus(status),
1332                ..
1333            } => status.code() == tonic::Code::OutOfRange,
1334            Error::ResponseExceededSizeLimit { .. } => true,
1335            _ => false,
1336        }
1337    }
1338}