1use std::any::Any;
16use std::sync::Arc;
17
18use common_datasource::compression::CompressionType;
19use common_error::ext::{BoxedError, ErrorExt, RetryHint};
20use common_error::status_code::StatusCode;
21use common_macro::stack_trace_debug;
22use common_memory_manager;
23use common_runtime::JoinError;
24use common_time::Timestamp;
25use common_time::timestamp::TimeUnit;
26use datatypes::arrow::error::ArrowError;
27use datatypes::prelude::ConcreteDataType;
28use object_store::ErrorKind;
29use object_store::error::retry_hint_from_opendal_error;
30use partition::error::Error as PartitionError;
31use prost::DecodeError;
32use snafu::{Location, Snafu};
33use store_api::ManifestVersion;
34use store_api::logstore::provider::Provider;
35use store_api::storage::{FileId, RegionId};
36use tokio::time::error::Elapsed;
37
38use crate::cache::file_cache::FileType;
39use crate::region::RegionRoleState;
40use crate::schedule::remote_job_scheduler::JobId;
41use crate::worker::WorkerId;
42
43#[derive(Snafu)]
44#[snafu(visibility(pub))]
45#[stack_trace_debug]
46pub enum Error {
47 #[snafu(display("Unexpected data type"))]
48 DataTypeMismatch {
49 source: datatypes::error::Error,
50 #[snafu(implicit)]
51 location: Location,
52 },
53
54 #[snafu(display("External error, context: {}", context))]
55 External {
56 source: BoxedError,
57 context: String,
58 #[snafu(implicit)]
59 location: Location,
60 },
61
62 #[snafu(display("OpenDAL operator failed"))]
63 OpenDal {
64 #[snafu(implicit)]
65 location: Location,
66 #[snafu(source)]
67 error: object_store::Error,
68 },
69
70 #[snafu(display(
71 "Manifest delta {} disappeared after it was listed, path: {}",
72 version,
73 path
74 ))]
75 ManifestDeltaNotFound {
76 version: ManifestVersion,
77 path: String,
78 #[snafu(source)]
79 error: object_store::Error,
80 #[snafu(implicit)]
81 location: Location,
82 },
83
84 #[snafu(display("Fail to compress object by {}, path: {}", compress_type, path))]
85 CompressObject {
86 compress_type: CompressionType,
87 path: String,
88 #[snafu(source)]
89 error: std::io::Error,
90 },
91
92 #[snafu(display("Fail to decompress object by {}, path: {}", compress_type, path))]
93 DecompressObject {
94 compress_type: CompressionType,
95 path: String,
96 #[snafu(source)]
97 error: std::io::Error,
98 },
99
100 #[snafu(display("Failed to ser/de json object"))]
101 SerdeJson {
102 #[snafu(implicit)]
103 location: Location,
104 #[snafu(source)]
105 error: serde_json::Error,
106 },
107
108 #[snafu(display("Failed to serialize column metadata"))]
109 SerializeColumnMetadata {
110 #[snafu(source)]
111 error: serde_json::Error,
112 #[snafu(implicit)]
113 location: Location,
114 },
115
116 #[snafu(display("Failed to serialize manifest, region_id: {}", region_id))]
117 SerializeManifest {
118 region_id: RegionId,
119 #[snafu(source)]
120 error: serde_json::Error,
121 #[snafu(implicit)]
122 location: Location,
123 },
124
125 #[snafu(display("Invalid scan index, start: {}, end: {}", start, end))]
126 InvalidScanIndex {
127 start: ManifestVersion,
128 end: ManifestVersion,
129 #[snafu(implicit)]
130 location: Location,
131 },
132
133 #[snafu(display("Invalid UTF-8 content"))]
134 Utf8 {
135 #[snafu(implicit)]
136 location: Location,
137 #[snafu(source)]
138 error: std::str::Utf8Error,
139 },
140
141 #[snafu(display("Cannot find RegionMetadata"))]
142 RegionMetadataNotFound {
143 #[snafu(implicit)]
144 location: Location,
145 },
146
147 #[snafu(display("Failed to join handle"))]
148 Join {
149 #[snafu(source)]
150 error: common_runtime::JoinError,
151 #[snafu(implicit)]
152 location: Location,
153 },
154
155 #[snafu(display("Worker {} is stopped", id))]
156 WorkerStopped {
157 id: WorkerId,
158 #[snafu(implicit)]
159 location: Location,
160 },
161
162 #[snafu(display("Failed to recv result"))]
163 Recv {
164 #[snafu(source)]
165 error: tokio::sync::oneshot::error::RecvError,
166 #[snafu(implicit)]
167 location: Location,
168 },
169
170 #[snafu(display("Invalid metadata, {}", reason))]
171 InvalidMeta {
172 reason: String,
173 #[snafu(implicit)]
174 location: Location,
175 },
176
177 #[snafu(display("Invalid region metadata"))]
178 InvalidMetadata {
179 source: store_api::metadata::MetadataError,
180 #[snafu(implicit)]
181 location: Location,
182 },
183
184 #[snafu(display("Failed to create RecordBatch from vectors"))]
185 NewRecordBatch {
186 #[snafu(implicit)]
187 location: Location,
188 #[snafu(source)]
189 error: ArrowError,
190 },
191
192 #[snafu(display("Failed to read parquet file, path: {}", path))]
193 ReadParquet {
194 path: String,
195 #[snafu(source)]
196 error: parquet::errors::ParquetError,
197 #[snafu(implicit)]
198 location: Location,
199 },
200
201 #[snafu(display("Failed to write parquet file"))]
202 WriteParquet {
203 #[snafu(source)]
204 error: parquet::errors::ParquetError,
205 #[snafu(implicit)]
206 location: Location,
207 },
208
209 #[snafu(display(
210 "Cannot assign a stable field id to native histogram sub-field '{}' of column id {} (unknown sub-field name or derived id overflows i32)",
211 field_name,
212 column_id
213 ))]
214 InvalidNativeHistogramSubfield {
215 column_id: i32,
216 field_name: String,
217 #[snafu(implicit)]
218 location: Location,
219 },
220
221 #[snafu(display(
222 "Native histogram column '{}' has no usable PARQUET:field_id to namespace its sub-field ids (missing, malformed, or exceeds i32::MAX)",
223 field_name
224 ))]
225 InvalidNativeHistogramFieldId {
226 field_name: String,
227 #[snafu(implicit)]
228 location: Location,
229 },
230
231 #[snafu(display("Region {} not found", region_id))]
232 RegionNotFound {
233 region_id: RegionId,
234 #[snafu(implicit)]
235 location: Location,
236 },
237
238 #[snafu(display("Object store not found: {}", object_store))]
239 ObjectStoreNotFound {
240 object_store: String,
241 #[snafu(implicit)]
242 location: Location,
243 },
244
245 #[snafu(display("Region {} is corrupted, reason: {}", region_id, reason))]
246 RegionCorrupted {
247 region_id: RegionId,
248 reason: String,
249 #[snafu(implicit)]
250 location: Location,
251 },
252
253 #[snafu(display("Invalid request to region {}, reason: {}", region_id, reason))]
254 InvalidRequest {
255 region_id: RegionId,
256 reason: String,
257 #[snafu(implicit)]
258 location: Location,
259 },
260
261 #[snafu(display(
262 "STALE_CURSOR: incremental query stale, region: {}, given_seq: {}, min_readable_seq: {}, retry_hint: FALLBACK_FULL_RECOMPUTE",
263 region_id,
264 given_seq,
265 min_readable_seq
266 ))]
267 IncrementalQueryStale {
268 region_id: RegionId,
269 given_seq: u64,
270 min_readable_seq: u64,
271 #[snafu(implicit)]
272 location: Location,
273 },
274
275 #[snafu(display(
276 "STALE_SNAPSHOT_FENCE: snapshot upper bound stale, region: {}, given_seq: {}, min_enforceable_seq: {}, retry_hint: REBIND_SNAPSHOT_FENCE",
277 region_id,
278 given_seq,
279 min_enforceable_seq
280 ))]
281 SnapshotFenceStale {
282 region_id: RegionId,
283 given_seq: u64,
284 min_enforceable_seq: u64,
285 #[snafu(implicit)]
286 location: Location,
287 },
288
289 #[snafu(display(
290 "SEQUENCE_RANGE_UNSUPPORTED: exact sequence-range read unsupported, region: {}, min_seq: {}, max_seq: {}, reason: {}, retry_hint: FALLBACK_MEMTABLE_ONLY_OR_FULL_RECOMPUTE",
291 region_id,
292 min_seq,
293 max_seq,
294 reason
295 ))]
296 SequenceRangeUnsupported {
297 region_id: RegionId,
298 min_seq: u64,
299 max_seq: u64,
300 reason: String,
301 #[snafu(implicit)]
302 location: Location,
303 },
304
305 #[snafu(display(
306 "region {} is unusable for sequence reads: file {} declares region {}",
307 region_id,
308 file_id,
309 file_region_id
310 ))]
311 RegionSequenceDomainBroken {
312 region_id: RegionId,
313 file_region_id: RegionId,
314 file_id: FileId,
315 #[snafu(implicit)]
316 location: Location,
317 },
318
319 #[snafu(display("Old manifest missing for region {}", region_id))]
320 MissingOldManifest {
321 region_id: RegionId,
322 #[snafu(implicit)]
323 location: Location,
324 },
325
326 #[snafu(display("New manifest missing for region {}", region_id))]
327 MissingNewManifest {
328 region_id: RegionId,
329 #[snafu(implicit)]
330 location: Location,
331 },
332
333 #[snafu(display("Manifest missing for region {}", region_id))]
334 MissingManifest {
335 region_id: RegionId,
336 #[snafu(implicit)]
337 location: Location,
338 },
339
340 #[snafu(display("File consistency check failed for file {}: {}", file_id, reason))]
341 InconsistentFile {
342 file_id: FileId,
343 reason: String,
344 #[snafu(implicit)]
345 location: Location,
346 },
347
348 #[snafu(display("Files lost during remapping: old={}, new={}", old_count, new_count))]
349 FilesLost {
350 old_count: usize,
351 new_count: usize,
352 #[snafu(implicit)]
353 location: Location,
354 },
355
356 #[snafu(display("No old manifests provided (need at least one for template)"))]
357 NoOldManifests {
358 #[snafu(implicit)]
359 location: Location,
360 },
361
362 #[snafu(display("Failed to fetch manifests"))]
363 FetchManifests {
364 #[snafu(implicit)]
365 location: Location,
366 source: BoxedError,
367 },
368
369 #[snafu(display("Partition expression missing for region {}", region_id))]
370 MissingPartitionExpr {
371 region_id: RegionId,
372 #[snafu(implicit)]
373 location: Location,
374 },
375
376 #[snafu(display("Failed to serialize partition expression: {}", source))]
377 SerializePartitionExpr {
378 #[snafu(source)]
379 source: PartitionError,
380 #[snafu(implicit)]
381 location: Location,
382 },
383
384 #[snafu(display(
385 "Failed to convert ConcreteDataType to ColumnDataType, reason: {}",
386 reason
387 ))]
388 ConvertColumnDataType {
389 reason: String,
390 source: api::error::Error,
391 #[snafu(implicit)]
392 location: Location,
393 },
394
395 #[snafu(display("Need to fill default value for region {}", region_id))]
398 FillDefault {
399 region_id: RegionId,
400 },
402
403 #[snafu(display(
404 "Failed to create default value for column {} of region {}",
405 column,
406 region_id
407 ))]
408 CreateDefault {
409 region_id: RegionId,
410 column: String,
411 source: datatypes::Error,
412 #[snafu(implicit)]
413 location: Location,
414 },
415
416 #[snafu(display("Failed to build entry, region_id: {}", region_id))]
417 BuildEntry {
418 region_id: RegionId,
419 #[snafu(implicit)]
420 location: Location,
421 source: BoxedError,
422 },
423
424 #[snafu(display("Failed to write WAL"))]
425 WriteWal {
426 #[snafu(implicit)]
427 location: Location,
428 source: BoxedError,
429 },
430
431 #[snafu(display("Failed to read WAL, provider: {}", provider))]
432 ReadWal {
433 provider: Provider,
434 #[snafu(implicit)]
435 location: Location,
436 source: BoxedError,
437 },
438
439 #[snafu(display("Failed to decode WAL entry, region_id: {}", region_id))]
440 DecodeWal {
441 region_id: RegionId,
442 #[snafu(implicit)]
443 location: Location,
444 #[snafu(source)]
445 error: DecodeError,
446 },
447
448 #[snafu(display("Failed to delete WAL, region_id: {}", region_id))]
449 DeleteWal {
450 region_id: RegionId,
451 #[snafu(implicit)]
452 location: Location,
453 source: BoxedError,
454 },
455
456 #[snafu(display("Failed to write region"))]
458 WriteGroup { source: Arc<Error> },
459
460 #[snafu(display("Invalid parquet SST file {}, reason: {}", file, reason))]
461 InvalidParquet {
462 file: String,
463 reason: String,
464 #[snafu(implicit)]
465 location: Location,
466 },
467
468 #[snafu(display("Invalid batch, {}", reason))]
469 InvalidBatch {
470 reason: String,
471 #[snafu(implicit)]
472 location: Location,
473 },
474
475 #[snafu(display("Invalid arrow record batch, {}", reason))]
476 InvalidRecordBatch {
477 reason: String,
478 #[snafu(implicit)]
479 location: Location,
480 },
481
482 #[snafu(display("Invalid wal read request, {}", reason))]
483 InvalidWalReadRequest {
484 reason: String,
485 #[snafu(implicit)]
486 location: Location,
487 },
488
489 #[snafu(display("Failed to convert array to vector"))]
490 ConvertVector {
491 #[snafu(implicit)]
492 location: Location,
493 source: datatypes::error::Error,
494 },
495
496 #[snafu(display("Failed to compute arrow arrays"))]
497 ComputeArrow {
498 #[snafu(implicit)]
499 location: Location,
500 #[snafu(source)]
501 error: datatypes::arrow::error::ArrowError,
502 },
503
504 #[snafu(display("Failed to evaluate partition filter"))]
505 EvalPartitionFilter {
506 #[snafu(implicit)]
507 location: Location,
508 #[snafu(source)]
509 error: datafusion::error::DataFusionError,
510 },
511
512 #[snafu(display("Failed to merge candidate series"))]
513 MergeCandidateSeries {
514 #[snafu(implicit)]
515 location: Location,
516 #[snafu(source)]
517 error: datafusion::error::DataFusionError,
518 },
519
520 #[snafu(display("Failed to compute vector"))]
521 ComputeVector {
522 #[snafu(implicit)]
523 location: Location,
524 source: datatypes::error::Error,
525 },
526
527 #[snafu(display("Primary key length mismatch, expect: {}, actual: {}", expect, actual))]
528 PrimaryKeyLengthMismatch {
529 expect: usize,
530 actual: usize,
531 #[snafu(implicit)]
532 location: Location,
533 },
534
535 #[snafu(display("Invalid sender",))]
536 InvalidSender {
537 #[snafu(implicit)]
538 location: Location,
539 },
540
541 #[snafu(display("Invalid scheduler state"))]
542 InvalidSchedulerState {
543 #[snafu(implicit)]
544 location: Location,
545 },
546
547 #[snafu(display("Failed to stop scheduler"))]
548 StopScheduler {
549 #[snafu(source)]
550 error: JoinError,
551 #[snafu(implicit)]
552 location: Location,
553 },
554
555 #[snafu(display(
556 "Failed to batch delete SST files, region id: {}, file ids: {:?}",
557 region_id,
558 file_ids
559 ))]
560 DeleteSsts {
561 region_id: RegionId,
562 file_ids: Vec<FileId>,
563 #[snafu(source)]
564 error: object_store::Error,
565 #[snafu(implicit)]
566 location: Location,
567 },
568
569 #[snafu(display("Failed to delete index file, file id: {}", file_id))]
570 DeleteIndex {
571 file_id: FileId,
572 #[snafu(source)]
573 error: object_store::Error,
574 #[snafu(implicit)]
575 location: Location,
576 },
577
578 #[snafu(display("Failed to batch delete index files, file ids: {:?}", file_ids))]
579 DeleteIndexes {
580 file_ids: Vec<FileId>,
581 #[snafu(source)]
582 error: object_store::Error,
583 #[snafu(implicit)]
584 location: Location,
585 },
586
587 #[snafu(display("Failed to flush region {}", region_id))]
588 FlushRegion {
589 region_id: RegionId,
590 source: Arc<Error>,
591 #[snafu(implicit)]
592 location: Location,
593 },
594
595 #[snafu(display("Region {} is dropped", region_id))]
596 RegionDropped {
597 region_id: RegionId,
598 #[snafu(implicit)]
599 location: Location,
600 },
601
602 #[snafu(display("Region {} is closed", region_id))]
603 RegionClosed {
604 region_id: RegionId,
605 #[snafu(implicit)]
606 location: Location,
607 },
608
609 #[snafu(display(
610 "Stale compaction execution for region {}, the region may have been reopened, truncated or the compaction was superseded",
611 region_id
612 ))]
613 StaleCompactionExecution {
614 region_id: RegionId,
615 #[snafu(implicit)]
616 location: Location,
617 },
618
619 #[snafu(display("Region {} is truncated", region_id))]
620 RegionTruncated {
621 region_id: RegionId,
622 #[snafu(implicit)]
623 location: Location,
624 },
625
626 #[snafu(display(
627 "Engine write buffer is full, rejecting write requests of region {}",
628 region_id,
629 ))]
630 RejectWrite {
631 region_id: RegionId,
632 #[snafu(implicit)]
633 location: Location,
634 },
635
636 #[snafu(display("Failed to compact region {}", region_id))]
637 CompactRegion {
638 region_id: RegionId,
639 source: Arc<Error>,
640 #[snafu(implicit)]
641 location: Location,
642 },
643
644 #[snafu(display("Failed to edit region {}", region_id))]
645 EditRegion {
646 region_id: RegionId,
647 source: Arc<Error>,
648 #[snafu(implicit)]
649 location: Location,
650 },
651
652 #[snafu(display(
653 "Failed to compat readers for region {}, reason: {}",
654 region_id,
655 reason,
656 ))]
657 CompatReader {
658 region_id: RegionId,
659 reason: String,
660 #[snafu(implicit)]
661 location: Location,
662 },
663
664 #[snafu(display("Invalue region req"))]
665 InvalidRegionRequest {
666 source: store_api::metadata::MetadataError,
667 #[snafu(implicit)]
668 location: Location,
669 },
670
671 #[snafu(display(
672 "Region {} is in {:?} state, which does not permit manifest updates.",
673 region_id,
674 state
675 ))]
676 UpdateManifest {
677 region_id: RegionId,
678 state: RegionRoleState,
679 #[snafu(implicit)]
680 location: Location,
681 },
682
683 #[snafu(display("Region {} is in {:?} state, expect: {:?}", region_id, state, expect))]
684 RegionState {
685 region_id: RegionId,
686 state: RegionRoleState,
687 expect: RegionRoleState,
688 #[snafu(implicit)]
689 location: Location,
690 },
691
692 #[snafu(display(
693 "Partition expr version mismatch for region {}: request {}, expected {}",
694 region_id,
695 request_version,
696 expected_version
697 ))]
698 PartitionExprVersionMismatch {
699 region_id: RegionId,
700 request_version: u64,
701 expected_version: u64,
702 #[snafu(implicit)]
703 location: Location,
704 },
705
706 #[snafu(display("Invalid options"))]
707 JsonOptions {
708 #[snafu(source)]
709 error: serde_json::Error,
710 #[snafu(implicit)]
711 location: Location,
712 },
713
714 #[snafu(display(
715 "Empty region directory, region_id: {}, region_dir: {}",
716 region_id,
717 region_dir,
718 ))]
719 EmptyRegionDir {
720 region_id: RegionId,
721 region_dir: String,
722 #[snafu(implicit)]
723 location: Location,
724 },
725
726 #[snafu(display("Empty manifest directory, manifest_dir: {}", manifest_dir,))]
727 EmptyManifestDir {
728 manifest_dir: String,
729 #[snafu(implicit)]
730 location: Location,
731 },
732
733 #[snafu(display("Column not found, column: {column}"))]
734 ColumnNotFound {
735 column: String,
736 #[snafu(implicit)]
737 location: Location,
738 },
739
740 #[snafu(display("Failed to build index applier"))]
741 BuildIndexApplier {
742 source: index::inverted_index::error::Error,
743 #[snafu(implicit)]
744 location: Location,
745 },
746
747 #[snafu(display("Failed to build index asynchronously in region {}", region_id))]
748 BuildIndexAsync {
749 region_id: RegionId,
750 source: Arc<Error>,
751 #[snafu(implicit)]
752 location: Location,
753 },
754
755 #[snafu(display("Failed to convert value"))]
756 ConvertValue {
757 source: datatypes::error::Error,
758 #[snafu(implicit)]
759 location: Location,
760 },
761
762 #[snafu(display("Failed to apply inverted index"))]
763 ApplyInvertedIndex {
764 source: index::inverted_index::error::Error,
765 #[snafu(implicit)]
766 location: Location,
767 },
768
769 #[snafu(display("Failed to apply bloom filter index"))]
770 ApplyBloomFilterIndex {
771 source: index::bloom_filter::error::Error,
772 #[snafu(implicit)]
773 location: Location,
774 },
775
776 #[snafu(display("Failed to push index value"))]
777 PushIndexValue {
778 source: index::inverted_index::error::Error,
779 #[snafu(implicit)]
780 location: Location,
781 },
782
783 #[snafu(display("Failed to write index completely"))]
784 IndexFinish {
785 source: index::inverted_index::error::Error,
786 #[snafu(implicit)]
787 location: Location,
788 },
789
790 #[snafu(display("Operate on aborted index"))]
791 OperateAbortedIndex {
792 #[snafu(implicit)]
793 location: Location,
794 },
795
796 #[snafu(display("Failed to read puffin blob"))]
797 PuffinReadBlob {
798 source: puffin::error::Error,
799 #[snafu(implicit)]
800 location: Location,
801 },
802
803 #[snafu(display("Failed to add blob to puffin file"))]
804 PuffinAddBlob {
805 source: puffin::error::Error,
806 #[snafu(implicit)]
807 location: Location,
808 },
809
810 #[snafu(display("Failed to clean dir {dir}"))]
811 CleanDir {
812 dir: String,
813 #[snafu(source)]
814 error: std::io::Error,
815 #[snafu(implicit)]
816 location: Location,
817 },
818
819 #[snafu(display("Invalid config, {reason}"))]
820 InvalidConfig {
821 reason: String,
822 #[snafu(implicit)]
823 location: Location,
824 },
825
826 #[snafu(display(
827 "Stale log entry found during replay, region: {}, flushed: {}, replayed: {}",
828 region_id,
829 flushed_entry_id,
830 unexpected_entry_id
831 ))]
832 StaleLogEntry {
833 region_id: RegionId,
834 flushed_entry_id: u64,
835 unexpected_entry_id: u64,
836 },
837
838 #[snafu(display(
839 "Failed to download file, region_id: {}, file_id: {}, file_type: {:?}",
840 region_id,
841 file_id,
842 file_type,
843 ))]
844 Download {
845 region_id: RegionId,
846 file_id: FileId,
847 file_type: FileType,
848 #[snafu(source)]
849 error: std::io::Error,
850 #[snafu(implicit)]
851 location: Location,
852 },
853
854 #[snafu(display(
855 "Failed to upload file, region_id: {}, file_id: {}, file_type: {:?}",
856 region_id,
857 file_id,
858 file_type,
859 ))]
860 Upload {
861 region_id: RegionId,
862 file_id: FileId,
863 file_type: FileType,
864 #[snafu(source)]
865 error: std::io::Error,
866 #[snafu(implicit)]
867 location: Location,
868 },
869
870 #[snafu(display("Failed to create directory {}", dir))]
871 CreateDir {
872 dir: String,
873 #[snafu(source)]
874 error: std::io::Error,
875 },
876
877 #[snafu(display("Record batch error"))]
878 RecordBatch {
879 source: common_recordbatch::error::Error,
880 #[snafu(implicit)]
881 location: Location,
882 },
883
884 #[snafu(display("BiErrors, first: {first}, second: {second}"))]
885 BiErrors {
886 first: Box<Error>,
887 second: Box<Error>,
888 #[snafu(implicit)]
889 location: Location,
890 },
891
892 #[snafu(display("Encode null value"))]
893 IndexEncodeNull {
894 #[snafu(implicit)]
895 location: Location,
896 },
897
898 #[snafu(display("Failed to encode memtable to Parquet bytes"))]
899 EncodeMemtable {
900 #[snafu(source)]
901 error: parquet::errors::ParquetError,
902 #[snafu(implicit)]
903 location: Location,
904 },
905
906 #[snafu(display("Partition {} out of range, {} in total", given, all))]
907 PartitionOutOfRange {
908 given: usize,
909 all: usize,
910 #[snafu(implicit)]
911 location: Location,
912 },
913
914 #[snafu(display("Failed to iter data part"))]
915 ReadDataPart {
916 #[snafu(implicit)]
917 location: Location,
918 #[snafu(source)]
919 error: parquet::errors::ParquetError,
920 },
921
922 #[snafu(display("Failed to read row group in memtable"))]
923 DecodeArrowRowGroup {
924 #[snafu(source)]
925 error: ArrowError,
926 #[snafu(implicit)]
927 location: Location,
928 },
929
930 #[snafu(display("Invalid region options, {}", reason))]
931 InvalidRegionOptions {
932 reason: String,
933 #[snafu(implicit)]
934 location: Location,
935 },
936
937 #[snafu(display("checksum mismatch (actual: {}, expected: {})", actual, expected))]
938 ChecksumMismatch { actual: u32, expected: u32 },
939
940 #[snafu(display(
941 "No checkpoint found, region: {}, last_version: {}",
942 region_id,
943 last_version
944 ))]
945 NoCheckpoint {
946 region_id: RegionId,
947 last_version: ManifestVersion,
948 #[snafu(implicit)]
949 location: Location,
950 },
951
952 #[snafu(display(
953 "No manifests found in range: [{}..{}), region: {}, last_version: {}",
954 start_version,
955 end_version,
956 region_id,
957 last_version
958 ))]
959 NoManifests {
960 region_id: RegionId,
961 start_version: ManifestVersion,
962 end_version: ManifestVersion,
963 last_version: ManifestVersion,
964 #[snafu(implicit)]
965 location: Location,
966 },
967
968 #[snafu(display(
969 "Failed to install manifest to {}, region: {}, available manifest version: {}, last version: {}",
970 target_version,
971 region_id,
972 available_version,
973 last_version
974 ))]
975 InstallManifestTo {
976 region_id: RegionId,
977 target_version: ManifestVersion,
978 available_version: ManifestVersion,
979 #[snafu(implicit)]
980 location: Location,
981 last_version: ManifestVersion,
982 },
983
984 #[snafu(display("Region {} is stopped", region_id))]
985 RegionStopped {
986 region_id: RegionId,
987 #[snafu(implicit)]
988 location: Location,
989 },
990
991 #[snafu(display(
992 "Time range predicate overflows, timestamp: {:?}, target unit: {}",
993 timestamp,
994 unit
995 ))]
996 TimeRangePredicateOverflow {
997 timestamp: Timestamp,
998 unit: TimeUnit,
999 #[snafu(implicit)]
1000 location: Location,
1001 },
1002
1003 #[snafu(display("Failed to open region"))]
1004 OpenRegion {
1005 #[snafu(implicit)]
1006 location: Location,
1007 source: Arc<Error>,
1008 },
1009
1010 #[snafu(display(
1011 "Region {} does not satisfy requirement '{}': {}",
1012 region_id,
1013 requirement,
1014 reason
1015 ))]
1016 RegionRequirement {
1017 region_id: RegionId,
1018 requirement: &'static str,
1019 reason: &'static str,
1020 #[snafu(implicit)]
1021 location: Location,
1022 },
1023
1024 #[snafu(display("Failed to parse job id"))]
1025 ParseJobId {
1026 #[snafu(implicit)]
1027 location: Location,
1028 #[snafu(source)]
1029 error: uuid::Error,
1030 },
1031
1032 #[snafu(display("Operation is not supported: {}", err_msg))]
1033 UnsupportedOperation {
1034 err_msg: String,
1035 #[snafu(implicit)]
1036 location: Location,
1037 },
1038
1039 #[snafu(display(
1040 "Failed to remotely compact region {} by job {:?} due to {}",
1041 region_id,
1042 job_id,
1043 reason
1044 ))]
1045 RemoteCompaction {
1046 region_id: RegionId,
1047 job_id: Option<JobId>,
1048 reason: String,
1049 #[snafu(implicit)]
1050 location: Location,
1051 },
1052
1053 #[snafu(display("Failed to initialize puffin stager"))]
1054 PuffinInitStager {
1055 source: puffin::error::Error,
1056 #[snafu(implicit)]
1057 location: Location,
1058 },
1059
1060 #[snafu(display("Failed to purge puffin stager"))]
1061 PuffinPurgeStager {
1062 source: puffin::error::Error,
1063 #[snafu(implicit)]
1064 location: Location,
1065 },
1066
1067 #[snafu(display("Failed to build puffin reader"))]
1068 PuffinBuildReader {
1069 source: puffin::error::Error,
1070 #[snafu(implicit)]
1071 location: Location,
1072 },
1073
1074 #[snafu(display("Failed to retrieve index options from column metadata"))]
1075 IndexOptions {
1076 #[snafu(implicit)]
1077 location: Location,
1078 source: datatypes::error::Error,
1079 column_name: String,
1080 },
1081
1082 #[snafu(display("Failed to create fulltext index creator"))]
1083 CreateFulltextCreator {
1084 source: index::fulltext_index::error::Error,
1085 #[snafu(implicit)]
1086 location: Location,
1087 },
1088
1089 #[snafu(display("Failed to cast vector of {from} to {to}"))]
1090 CastVector {
1091 #[snafu(implicit)]
1092 location: Location,
1093 from: ConcreteDataType,
1094 to: ConcreteDataType,
1095 source: datatypes::error::Error,
1096 },
1097
1098 #[snafu(display("Failed to push text to fulltext index"))]
1099 FulltextPushText {
1100 source: index::fulltext_index::error::Error,
1101 #[snafu(implicit)]
1102 location: Location,
1103 },
1104
1105 #[snafu(display("Failed to finalize fulltext index creator"))]
1106 FulltextFinish {
1107 source: index::fulltext_index::error::Error,
1108 #[snafu(implicit)]
1109 location: Location,
1110 },
1111
1112 #[snafu(display("Failed to apply fulltext index"))]
1113 ApplyFulltextIndex {
1114 source: index::fulltext_index::error::Error,
1115 #[snafu(implicit)]
1116 location: Location,
1117 },
1118
1119 #[snafu(display("SST file {} does not contain valid stats info", file_path))]
1120 StatsNotPresent {
1121 file_path: String,
1122 #[snafu(implicit)]
1123 location: Location,
1124 },
1125
1126 #[snafu(display("Failed to decode stats of file {}", file_path))]
1127 DecodeStats {
1128 file_path: String,
1129 #[snafu(implicit)]
1130 location: Location,
1131 },
1132
1133 #[snafu(display("Invalid SST primary key range: {reason}"))]
1134 InvalidPrimaryKeyRange {
1135 reason: String,
1136 #[snafu(implicit)]
1137 location: Location,
1138 },
1139
1140 #[snafu(display("Failed to decode SST primary key range {endpoint} endpoint"))]
1141 DecodePrimaryKeyRange {
1142 endpoint: &'static str,
1143 source: mito_codec::error::Error,
1144 #[snafu(implicit)]
1145 location: Location,
1146 },
1147
1148 #[snafu(display("Region {} is busy", region_id))]
1149 RegionBusy {
1150 region_id: RegionId,
1151 #[snafu(implicit)]
1152 location: Location,
1153 },
1154
1155 #[snafu(display("Failed to get schema metadata"))]
1156 GetSchemaMetadata {
1157 source: common_meta::error::Error,
1158 #[snafu(implicit)]
1159 location: Location,
1160 },
1161
1162 #[snafu(display("Timeout"))]
1163 Timeout {
1164 #[snafu(source)]
1165 error: Elapsed,
1166 #[snafu(implicit)]
1167 location: Location,
1168 },
1169
1170 #[snafu(display("Failed to read file metadata"))]
1171 Metadata {
1172 #[snafu(source)]
1173 error: std::io::Error,
1174 #[snafu(implicit)]
1175 location: Location,
1176 },
1177
1178 #[snafu(display("Failed to push value to bloom filter"))]
1179 PushBloomFilterValue {
1180 source: index::bloom_filter::error::Error,
1181 #[snafu(implicit)]
1182 location: Location,
1183 },
1184
1185 #[snafu(display("Failed to finish bloom filter"))]
1186 BloomFilterFinish {
1187 source: index::bloom_filter::error::Error,
1188 #[snafu(implicit)]
1189 location: Location,
1190 },
1191
1192 #[snafu(display("Manual compaction is override by following operations."))]
1193 ManualCompactionOverride {},
1194
1195 #[snafu(display("Manual compaction is already running for region {region_id}."))]
1196 ManualCompactionAlreadyRunning { region_id: RegionId },
1197
1198 #[snafu(display("Compaction is cancelled."))]
1199 CompactionCancelled {},
1200
1201 #[snafu(display("Flush is cancelled."))]
1202 FlushCancelled {},
1203
1204 #[snafu(display("Compaction memory exhausted for region {region_id} (policy: {policy})",))]
1205 CompactionMemoryExhausted {
1206 region_id: RegionId,
1207 policy: String,
1208 #[snafu(source)]
1209 source: common_memory_manager::Error,
1210 #[snafu(implicit)]
1211 location: Location,
1212 },
1213
1214 #[snafu(display(
1215 "Incompatible WAL provider change. This is typically caused by changing WAL provider in database config file without completely cleaning existing files. Global provider: {}, region provider: {}",
1216 global,
1217 region
1218 ))]
1219 IncompatibleWalProviderChange { global: String, region: String },
1220
1221 #[snafu(display("Expected mito manifest info"))]
1222 MitoManifestInfo {
1223 #[snafu(implicit)]
1224 location: Location,
1225 },
1226
1227 #[snafu(display("Failed to scan series"))]
1228 ScanSeries {
1229 #[snafu(implicit)]
1230 location: Location,
1231 source: Arc<Error>,
1232 },
1233
1234 #[snafu(display("Partition {} scan multiple times", partition))]
1235 ScanMultiTimes {
1236 partition: usize,
1237 #[snafu(implicit)]
1238 location: Location,
1239 },
1240
1241 #[snafu(display("Invalid partition expression: {}", expr))]
1242 InvalidPartitionExpr {
1243 expr: String,
1244 #[snafu(implicit)]
1245 location: Location,
1246 source: partition::error::Error,
1247 },
1248
1249 #[snafu(display("Failed to decode bulk wal entry"))]
1250 ConvertBulkWalEntry {
1251 #[snafu(implicit)]
1252 location: Location,
1253 source: common_grpc::Error,
1254 },
1255
1256 #[snafu(display("Failed to encode"))]
1257 Encode {
1258 #[snafu(implicit)]
1259 location: Location,
1260 source: mito_codec::error::Error,
1261 },
1262
1263 #[snafu(display("Failed to decode"))]
1264 Decode {
1265 #[snafu(implicit)]
1266 location: Location,
1267 source: mito_codec::error::Error,
1268 },
1269
1270 #[snafu(display("Unexpected: {reason}"))]
1271 Unexpected {
1272 reason: String,
1273 #[snafu(implicit)]
1274 location: Location,
1275 },
1276
1277 #[cfg(feature = "enterprise")]
1278 #[snafu(display("Failed to scan external range"))]
1279 ScanExternalRange {
1280 source: BoxedError,
1281 #[snafu(implicit)]
1282 location: Location,
1283 },
1284
1285 #[snafu(display(
1286 "Inconsistent timestamp column length, expect: {}, actual: {}",
1287 expected,
1288 actual
1289 ))]
1290 InconsistentTimestampLength {
1291 expected: usize,
1292 actual: usize,
1293 #[snafu(implicit)]
1294 location: Location,
1295 },
1296
1297 #[snafu(display(
1298 "Too many files to read concurrently: {}, max allowed: {}",
1299 actual,
1300 max
1301 ))]
1302 TooManyFilesToRead {
1303 actual: usize,
1304 max: usize,
1305 #[snafu(implicit)]
1306 location: Location,
1307 },
1308
1309 #[snafu(display("Duration out of range: {input:?}"))]
1310 DurationOutOfRange {
1311 input: std::time::Duration,
1312 #[snafu(source)]
1313 error: chrono::OutOfRangeError,
1314 #[snafu(implicit)]
1315 location: Location,
1316 },
1317
1318 #[snafu(display("GC job permit exhausted"))]
1319 TooManyGcJobs {
1320 #[snafu(implicit)]
1321 location: Location,
1322 },
1323
1324 #[snafu(display(
1325 "Staging partition expr mismatch, manifest: {:?}, request: {}",
1326 manifest_expr,
1327 request_expr
1328 ))]
1329 StagingPartitionExprMismatch {
1330 manifest_expr: Option<String>,
1331 request_expr: String,
1332 #[snafu(implicit)]
1333 location: Location,
1334 },
1335
1336 #[snafu(display(
1337 "Invalid source and target region, source: {}, target: {}",
1338 source_region_id,
1339 target_region_id
1340 ))]
1341 InvalidSourceAndTargetRegion {
1342 source_region_id: RegionId,
1343 target_region_id: RegionId,
1344 #[snafu(implicit)]
1345 location: Location,
1346 },
1347
1348 #[snafu(display("Failed to prune file"))]
1349 PruneFile {
1350 source: Arc<Error>,
1351 #[snafu(implicit)]
1352 location: Location,
1353 },
1354
1355 #[snafu(display("Failed to cast column"))]
1356 CastColumn {
1357 #[snafu(source)]
1358 error: datafusion::error::DataFusionError,
1359 #[snafu(implicit)]
1360 location: Location,
1361 },
1362
1363 #[snafu(display("Failed to generate Arrow schema from Parquet file: {}", file))]
1364 ParquetToArrowSchema {
1365 file: String,
1366 #[snafu(source)]
1367 error: parquet::errors::ParquetError,
1368 #[snafu(implicit)]
1369 location: Location,
1370 },
1371
1372 #[snafu(display(
1373 "Region {} is in {:?} state, expect: Writable, Staging or Downgrading",
1374 region_id,
1375 state
1376 ))]
1377 FlushableRegionState {
1378 region_id: RegionId,
1379 state: RegionRoleState,
1380 #[snafu(implicit)]
1381 location: Location,
1382 },
1383}
1384
1385pub type Result<T, E = Error> = std::result::Result<T, E>;
1386
1387impl Error {
1388 pub(crate) fn is_fill_default(&self) -> bool {
1390 matches!(self, Error::FillDefault { .. })
1391 }
1392
1393 pub(crate) fn is_object_not_found(&self) -> bool {
1395 match self {
1396 Error::OpenDal { error, .. } => error.kind() == ErrorKind::NotFound,
1397 Error::ManifestDeltaNotFound { .. } => true,
1398 _ => false,
1399 }
1400 }
1401
1402 pub(crate) fn may_have_persisted_manifest_update(&self) -> bool {
1407 match self {
1408 Error::UpdateManifest { .. }
1409 | Error::RegionState { .. }
1410 | Error::RegionTruncated { .. }
1411 | Error::RegionStopped { .. }
1412 | Error::SerdeJson { .. }
1413 | Error::CompressObject { .. } => false,
1414 Error::OpenDal { error, .. } => !matches!(
1415 error.kind(),
1416 ErrorKind::Unsupported
1417 | ErrorKind::ConfigInvalid
1418 | ErrorKind::NotFound
1419 | ErrorKind::PermissionDenied
1420 | ErrorKind::IsADirectory
1421 | ErrorKind::NotADirectory
1422 | ErrorKind::AlreadyExists
1423 | ErrorKind::RateLimited
1424 | ErrorKind::IsSameFile
1425 | ErrorKind::ConditionNotMatch
1426 | ErrorKind::RangeNotSatisfied
1427 ),
1428 _ => true,
1429 }
1430 }
1431}
1432
1433impl ErrorExt for Error {
1434 fn status_code(&self) -> StatusCode {
1435 use Error::*;
1436
1437 match self {
1438 DataTypeMismatch { source, .. } => source.status_code(),
1439 OpenDal { .. } | ManifestDeltaNotFound { .. } | ReadParquet { .. } => {
1440 StatusCode::StorageUnavailable
1441 }
1442 WriteWal { source, .. } | ReadWal { source, .. } | DeleteWal { source, .. } => {
1443 source.status_code()
1444 }
1445 CompressObject { .. }
1446 | DecompressObject { .. }
1447 | SerdeJson { .. }
1448 | Utf8 { .. }
1449 | NewRecordBatch { .. }
1450 | RegionCorrupted { .. }
1451 | InconsistentFile { .. }
1452 | CreateDefault { .. }
1453 | InvalidParquet { .. }
1454 | OperateAbortedIndex { .. }
1455 | IndexEncodeNull { .. }
1456 | NoCheckpoint { .. }
1457 | NoManifests { .. }
1458 | FilesLost { .. }
1459 | InstallManifestTo { .. }
1460 | Unexpected { .. }
1461 | SerializeColumnMetadata { .. }
1462 | SerializeManifest { .. }
1463 | StagingPartitionExprMismatch { .. } => StatusCode::Unexpected,
1464
1465 RegionNotFound { .. } => StatusCode::RegionNotFound,
1466 ObjectStoreNotFound { .. }
1467 | InvalidScanIndex { .. }
1468 | InvalidMeta { .. }
1469 | InvalidRequest { .. }
1470 | PartitionExprVersionMismatch { .. }
1471 | FillDefault { .. }
1472 | ConvertColumnDataType { .. }
1473 | ColumnNotFound { .. }
1474 | InvalidMetadata { .. }
1475 | InvalidRegionOptions { .. }
1476 | InvalidWalReadRequest { .. }
1477 | PartitionOutOfRange { .. }
1478 | ParseJobId { .. }
1479 | DurationOutOfRange { .. }
1480 | MissingOldManifest { .. }
1481 | MissingNewManifest { .. }
1482 | MissingManifest { .. }
1483 | NoOldManifests { .. }
1484 | MissingPartitionExpr { .. }
1485 | SerializePartitionExpr { .. }
1486 | InvalidSourceAndTargetRegion { .. } => StatusCode::InvalidArguments,
1487
1488 IncrementalQueryStale { .. } | SnapshotFenceStale { .. } => StatusCode::RequestOutdated,
1489
1490 SequenceRangeUnsupported { .. } => StatusCode::Unsupported,
1491
1492 RegionSequenceDomainBroken { .. }
1493 | RegionMetadataNotFound { .. }
1494 | Join { .. }
1495 | WorkerStopped { .. }
1496 | Recv { .. }
1497 | DecodeWal { .. }
1498 | ComputeArrow { .. }
1499 | EvalPartitionFilter { .. }
1500 | MergeCandidateSeries { .. }
1501 | BiErrors { .. }
1502 | StopScheduler { .. }
1503 | ComputeVector { .. }
1504 | EncodeMemtable { .. }
1505 | CreateDir { .. }
1506 | ReadDataPart { .. }
1507 | BuildEntry { .. }
1508 | Metadata { .. }
1509 | CastColumn { .. }
1510 | MitoManifestInfo { .. }
1511 | ParquetToArrowSchema { .. } => StatusCode::Internal,
1512
1513 FetchManifests { source, .. } => source.status_code(),
1514
1515 OpenRegion { source, .. } => source.status_code(),
1516
1517 WriteParquet { .. } => StatusCode::StorageUnavailable,
1518 WriteGroup { source, .. } => source.status_code(),
1519 InvalidBatch { .. } => StatusCode::InvalidArguments,
1520 InvalidRecordBatch { .. } => StatusCode::InvalidArguments,
1521 ConvertVector { source, .. } => source.status_code(),
1522
1523 PrimaryKeyLengthMismatch { .. } => StatusCode::InvalidArguments,
1524 InvalidSender { .. } => StatusCode::InvalidArguments,
1525 InvalidSchedulerState { .. } => StatusCode::InvalidArguments,
1526 RegionRequirement { .. } => StatusCode::InvalidArguments,
1527 DeleteSsts { .. } | DeleteIndex { .. } | DeleteIndexes { .. } => {
1528 StatusCode::StorageUnavailable
1529 }
1530 FlushRegion { source, .. } | BuildIndexAsync { source, .. } => source.status_code(),
1531 RegionDropped { .. } => StatusCode::Cancelled,
1532 RegionClosed { .. } => StatusCode::Cancelled,
1533 StaleCompactionExecution { .. } => StatusCode::Cancelled,
1534 RegionTruncated { .. } => StatusCode::Cancelled,
1535 RejectWrite { .. } => StatusCode::StorageUnavailable,
1536 CompactRegion { source, .. } => source.status_code(),
1537 EditRegion { source, .. } => source.status_code(),
1538 CompatReader { .. } => StatusCode::Unexpected,
1539 InvalidRegionRequest { source, .. } => source.status_code(),
1540 RegionState { .. } | UpdateManifest { .. } => StatusCode::RegionNotReady,
1541 JsonOptions { .. } => StatusCode::InvalidArguments,
1542 EmptyRegionDir { .. } | EmptyManifestDir { .. } => StatusCode::RegionNotFound,
1543 ConvertValue { source, .. } => source.status_code(),
1544 ApplyBloomFilterIndex { source, .. } => source.status_code(),
1545 InvalidPartitionExpr { source, .. } => source.status_code(),
1546 BuildIndexApplier { source, .. }
1547 | PushIndexValue { source, .. }
1548 | ApplyInvertedIndex { source, .. }
1549 | IndexFinish { source, .. } => source.status_code(),
1550 PuffinReadBlob { source, .. }
1551 | PuffinAddBlob { source, .. }
1552 | PuffinInitStager { source, .. }
1553 | PuffinBuildReader { source, .. }
1554 | PuffinPurgeStager { source, .. } => source.status_code(),
1555 CleanDir { .. } => StatusCode::Unexpected,
1556 InvalidConfig { .. } => StatusCode::InvalidArguments,
1557 StaleLogEntry { .. }
1558 | InvalidNativeHistogramSubfield { .. }
1559 | InvalidNativeHistogramFieldId { .. } => StatusCode::Unexpected,
1560
1561 External { source, .. } => source.status_code(),
1562
1563 RecordBatch { source, .. } => source.status_code(),
1564
1565 Download { .. } | Upload { .. } => StatusCode::StorageUnavailable,
1566 ChecksumMismatch { .. } => StatusCode::Unexpected,
1567 RegionStopped { .. } => StatusCode::RegionNotReady,
1568 TimeRangePredicateOverflow { .. } => StatusCode::InvalidArguments,
1569 UnsupportedOperation { .. } => StatusCode::Unsupported,
1570 RemoteCompaction { .. } => StatusCode::Unexpected,
1571
1572 IndexOptions { source, .. } => source.status_code(),
1573 CreateFulltextCreator { source, .. } => source.status_code(),
1574 CastVector { source, .. } => source.status_code(),
1575 FulltextPushText { source, .. }
1576 | FulltextFinish { source, .. }
1577 | ApplyFulltextIndex { source, .. } => source.status_code(),
1578 DecodeStats { .. }
1579 | StatsNotPresent { .. }
1580 | InvalidPrimaryKeyRange { .. }
1581 | DecodePrimaryKeyRange { .. } => StatusCode::Internal,
1582 RegionBusy { .. } => StatusCode::RegionBusy,
1583 GetSchemaMetadata { source, .. } => source.status_code(),
1584 Timeout { .. } => StatusCode::Cancelled,
1585
1586 DecodeArrowRowGroup { .. } => StatusCode::Internal,
1587
1588 PushBloomFilterValue { source, .. } | BloomFilterFinish { source, .. } => {
1589 source.status_code()
1590 }
1591
1592 ManualCompactionOverride {} | CompactionCancelled {} | FlushCancelled {} => {
1593 StatusCode::Cancelled
1594 }
1595
1596 ManualCompactionAlreadyRunning { .. } => StatusCode::RegionBusy,
1600
1601 CompactionMemoryExhausted { source, .. } => source.status_code(),
1602
1603 IncompatibleWalProviderChange { .. } => StatusCode::InvalidArguments,
1604
1605 ScanSeries { source, .. } => source.status_code(),
1606
1607 ScanMultiTimes { .. } => StatusCode::InvalidArguments,
1608 ConvertBulkWalEntry { source, .. } => source.status_code(),
1609
1610 Encode { source, .. } | Decode { source, .. } => source.status_code(),
1611
1612 #[cfg(feature = "enterprise")]
1613 ScanExternalRange { source, .. } => source.status_code(),
1614
1615 InconsistentTimestampLength { .. } => StatusCode::InvalidArguments,
1616
1617 TooManyFilesToRead { .. } | TooManyGcJobs { .. } => StatusCode::RateLimited,
1618
1619 PruneFile { source, .. } => source.status_code(),
1620
1621 FlushableRegionState { .. } => StatusCode::RegionNotReady,
1622 }
1623 }
1624
1625 fn as_any(&self) -> &dyn Any {
1626 self
1627 }
1628
1629 fn retry_hint(&self) -> RetryHint {
1630 use Error::*;
1631
1632 match self {
1633 ReadParquet { .. }
1634 | WriteParquet { .. }
1635 | RejectWrite { .. }
1636 | Download { .. }
1637 | Upload { .. }
1638 | RegionState { .. }
1639 | UpdateManifest { .. }
1640 | RegionStopped { .. }
1641 | RegionBusy { .. }
1642 | ManualCompactionAlreadyRunning { .. }
1643 | FlushableRegionState { .. }
1644 | ManifestDeltaNotFound { .. } => RetryHint::Retryable,
1645
1646 OpenDal { error, .. }
1647 | DeleteSsts { error, .. }
1648 | DeleteIndex { error, .. }
1649 | DeleteIndexes { error, .. } => retry_hint_from_opendal_error(error),
1650
1651 WriteWal { source, .. }
1652 | ReadWal { source, .. }
1653 | DeleteWal { source, .. }
1654 | FetchManifests { source, .. }
1655 | External { source, .. } => source.retry_hint(),
1656
1657 OpenRegion { source, .. }
1658 | WriteGroup { source, .. }
1659 | FlushRegion { source, .. }
1660 | BuildIndexAsync { source, .. }
1661 | CompactRegion { source, .. }
1662 | EditRegion { source, .. }
1663 | ScanSeries { source, .. }
1664 | PruneFile { source, .. } => source.retry_hint(),
1665
1666 DataTypeMismatch { source, .. }
1667 | ConvertVector { source, .. }
1668 | ConvertValue { source, .. }
1669 | IndexOptions { source, .. }
1670 | CastVector { source, .. } => source.retry_hint(),
1671
1672 BuildIndexApplier { source, .. }
1673 | PushIndexValue { source, .. }
1674 | ApplyInvertedIndex { source, .. }
1675 | IndexFinish { source, .. } => source.retry_hint(),
1676
1677 ApplyBloomFilterIndex { source, .. }
1678 | PushBloomFilterValue { source, .. }
1679 | BloomFilterFinish { source, .. } => source.retry_hint(),
1680
1681 PuffinReadBlob { source, .. }
1682 | PuffinAddBlob { source, .. }
1683 | PuffinInitStager { source, .. }
1684 | PuffinBuildReader { source, .. }
1685 | PuffinPurgeStager { source, .. } => source.retry_hint(),
1686
1687 CreateFulltextCreator { source, .. }
1688 | FulltextPushText { source, .. }
1689 | FulltextFinish { source, .. }
1690 | ApplyFulltextIndex { source, .. } => source.retry_hint(),
1691
1692 InvalidRegionRequest { source, .. } => source.retry_hint(),
1693 InvalidPartitionExpr { source, .. } => source.retry_hint(),
1694 RecordBatch { source, .. } => source.retry_hint(),
1695 GetSchemaMetadata { source, .. } => source.retry_hint(),
1696 CompactionMemoryExhausted { source, .. } => source.retry_hint(),
1697 ConvertBulkWalEntry { source, .. } => source.retry_hint(),
1698 Encode { source, .. } | Decode { source, .. } => source.retry_hint(),
1699
1700 #[cfg(feature = "enterprise")]
1701 ScanExternalRange { source, .. } => source.retry_hint(),
1702
1703 _ => RetryHint::NonRetryable,
1704 }
1705 }
1706}
1707
1708#[cfg(test)]
1709mod tests {
1710 use snafu::IntoError;
1711
1712 use super::*;
1713
1714 #[test]
1715 fn test_manifest_update_persistence() {
1716 let rejected_kinds = [
1717 ErrorKind::Unsupported,
1718 ErrorKind::ConfigInvalid,
1719 ErrorKind::NotFound,
1720 ErrorKind::PermissionDenied,
1721 ErrorKind::IsADirectory,
1722 ErrorKind::NotADirectory,
1723 ErrorKind::AlreadyExists,
1724 ErrorKind::RateLimited,
1725 ErrorKind::IsSameFile,
1726 ErrorKind::ConditionNotMatch,
1727 ErrorKind::RangeNotSatisfied,
1728 ];
1729 for kind in rejected_kinds {
1730 let error = OpenDalSnafu {}.into_error(object_store::Error::new(kind, "test"));
1731 assert!(
1732 !error.may_have_persisted_manifest_update(),
1733 "error kind {kind:?} should prove the manifest was not persisted"
1734 );
1735 }
1736
1737 let error =
1738 OpenDalSnafu {}.into_error(object_store::Error::new(ErrorKind::Unexpected, "test"));
1739 assert!(error.may_have_persisted_manifest_update());
1740
1741 let region_id = RegionId::new(1, 1);
1742 let error = RegionTruncatedSnafu { region_id }.build();
1743 assert!(!error.may_have_persisted_manifest_update());
1744
1745 let error = RegionMetadataNotFoundSnafu {}.build();
1747 assert!(error.may_have_persisted_manifest_update());
1748 }
1749}