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