1use 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 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 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 pub fn is_retry_later(&self) -> bool {
1324 matches!(
1325 self,
1326 Error::RetryLater { .. } | Error::GetLatestCacheRetryExceeded { .. }
1327 )
1328 }
1329
1330 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 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}