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