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 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 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 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 pub fn is_retry_later(&self) -> bool {
1310 matches!(
1311 self,
1312 Error::RetryLater { .. } | Error::GetLatestCacheRetryExceeded { .. }
1313 )
1314 }
1315
1316 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 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}