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 #[cfg(feature = "vector_index")]
777 #[snafu(display("Failed to apply vector index: {}", reason))]
778 ApplyVectorIndex {
779 reason: String,
780 #[snafu(implicit)]
781 location: Location,
782 },
783
784 #[snafu(display("Failed to push index value"))]
785 PushIndexValue {
786 source: index::inverted_index::error::Error,
787 #[snafu(implicit)]
788 location: Location,
789 },
790
791 #[snafu(display("Failed to write index completely"))]
792 IndexFinish {
793 source: index::inverted_index::error::Error,
794 #[snafu(implicit)]
795 location: Location,
796 },
797
798 #[snafu(display("Operate on aborted index"))]
799 OperateAbortedIndex {
800 #[snafu(implicit)]
801 location: Location,
802 },
803
804 #[snafu(display("Failed to read puffin blob"))]
805 PuffinReadBlob {
806 source: puffin::error::Error,
807 #[snafu(implicit)]
808 location: Location,
809 },
810
811 #[snafu(display("Failed to add blob to puffin file"))]
812 PuffinAddBlob {
813 source: puffin::error::Error,
814 #[snafu(implicit)]
815 location: Location,
816 },
817
818 #[snafu(display("Failed to clean dir {dir}"))]
819 CleanDir {
820 dir: String,
821 #[snafu(source)]
822 error: std::io::Error,
823 #[snafu(implicit)]
824 location: Location,
825 },
826
827 #[snafu(display("Invalid config, {reason}"))]
828 InvalidConfig {
829 reason: String,
830 #[snafu(implicit)]
831 location: Location,
832 },
833
834 #[snafu(display(
835 "Stale log entry found during replay, region: {}, flushed: {}, replayed: {}",
836 region_id,
837 flushed_entry_id,
838 unexpected_entry_id
839 ))]
840 StaleLogEntry {
841 region_id: RegionId,
842 flushed_entry_id: u64,
843 unexpected_entry_id: u64,
844 },
845
846 #[snafu(display(
847 "Failed to download file, region_id: {}, file_id: {}, file_type: {:?}",
848 region_id,
849 file_id,
850 file_type,
851 ))]
852 Download {
853 region_id: RegionId,
854 file_id: FileId,
855 file_type: FileType,
856 #[snafu(source)]
857 error: std::io::Error,
858 #[snafu(implicit)]
859 location: Location,
860 },
861
862 #[snafu(display(
863 "Failed to upload file, region_id: {}, file_id: {}, file_type: {:?}",
864 region_id,
865 file_id,
866 file_type,
867 ))]
868 Upload {
869 region_id: RegionId,
870 file_id: FileId,
871 file_type: FileType,
872 #[snafu(source)]
873 error: std::io::Error,
874 #[snafu(implicit)]
875 location: Location,
876 },
877
878 #[snafu(display("Failed to create directory {}", dir))]
879 CreateDir {
880 dir: String,
881 #[snafu(source)]
882 error: std::io::Error,
883 },
884
885 #[snafu(display("Record batch error"))]
886 RecordBatch {
887 source: common_recordbatch::error::Error,
888 #[snafu(implicit)]
889 location: Location,
890 },
891
892 #[snafu(display("BiErrors, first: {first}, second: {second}"))]
893 BiErrors {
894 first: Box<Error>,
895 second: Box<Error>,
896 #[snafu(implicit)]
897 location: Location,
898 },
899
900 #[snafu(display("Encode null value"))]
901 IndexEncodeNull {
902 #[snafu(implicit)]
903 location: Location,
904 },
905
906 #[snafu(display("Failed to encode memtable to Parquet bytes"))]
907 EncodeMemtable {
908 #[snafu(source)]
909 error: parquet::errors::ParquetError,
910 #[snafu(implicit)]
911 location: Location,
912 },
913
914 #[snafu(display("Partition {} out of range, {} in total", given, all))]
915 PartitionOutOfRange {
916 given: usize,
917 all: usize,
918 #[snafu(implicit)]
919 location: Location,
920 },
921
922 #[snafu(display("Failed to iter data part"))]
923 ReadDataPart {
924 #[snafu(implicit)]
925 location: Location,
926 #[snafu(source)]
927 error: parquet::errors::ParquetError,
928 },
929
930 #[snafu(display("Failed to read row group in memtable"))]
931 DecodeArrowRowGroup {
932 #[snafu(source)]
933 error: ArrowError,
934 #[snafu(implicit)]
935 location: Location,
936 },
937
938 #[snafu(display("Invalid region options, {}", reason))]
939 InvalidRegionOptions {
940 reason: String,
941 #[snafu(implicit)]
942 location: Location,
943 },
944
945 #[snafu(display("checksum mismatch (actual: {}, expected: {})", actual, expected))]
946 ChecksumMismatch { actual: u32, expected: u32 },
947
948 #[snafu(display(
949 "No checkpoint found, region: {}, last_version: {}",
950 region_id,
951 last_version
952 ))]
953 NoCheckpoint {
954 region_id: RegionId,
955 last_version: ManifestVersion,
956 #[snafu(implicit)]
957 location: Location,
958 },
959
960 #[snafu(display(
961 "No manifests found in range: [{}..{}), region: {}, last_version: {}",
962 start_version,
963 end_version,
964 region_id,
965 last_version
966 ))]
967 NoManifests {
968 region_id: RegionId,
969 start_version: ManifestVersion,
970 end_version: ManifestVersion,
971 last_version: ManifestVersion,
972 #[snafu(implicit)]
973 location: Location,
974 },
975
976 #[snafu(display(
977 "Failed to install manifest to {}, region: {}, available manifest version: {}, last version: {}",
978 target_version,
979 region_id,
980 available_version,
981 last_version
982 ))]
983 InstallManifestTo {
984 region_id: RegionId,
985 target_version: ManifestVersion,
986 available_version: ManifestVersion,
987 #[snafu(implicit)]
988 location: Location,
989 last_version: ManifestVersion,
990 },
991
992 #[snafu(display("Region {} is stopped", region_id))]
993 RegionStopped {
994 region_id: RegionId,
995 #[snafu(implicit)]
996 location: Location,
997 },
998
999 #[snafu(display(
1000 "Time range predicate overflows, timestamp: {:?}, target unit: {}",
1001 timestamp,
1002 unit
1003 ))]
1004 TimeRangePredicateOverflow {
1005 timestamp: Timestamp,
1006 unit: TimeUnit,
1007 #[snafu(implicit)]
1008 location: Location,
1009 },
1010
1011 #[snafu(display("Failed to open region"))]
1012 OpenRegion {
1013 #[snafu(implicit)]
1014 location: Location,
1015 source: Arc<Error>,
1016 },
1017
1018 #[snafu(display(
1019 "Region {} does not satisfy requirement '{}': {}",
1020 region_id,
1021 requirement,
1022 reason
1023 ))]
1024 RegionRequirement {
1025 region_id: RegionId,
1026 requirement: &'static str,
1027 reason: &'static str,
1028 #[snafu(implicit)]
1029 location: Location,
1030 },
1031
1032 #[snafu(display("Failed to parse job id"))]
1033 ParseJobId {
1034 #[snafu(implicit)]
1035 location: Location,
1036 #[snafu(source)]
1037 error: uuid::Error,
1038 },
1039
1040 #[snafu(display("Operation is not supported: {}", err_msg))]
1041 UnsupportedOperation {
1042 err_msg: String,
1043 #[snafu(implicit)]
1044 location: Location,
1045 },
1046
1047 #[snafu(display(
1048 "Failed to remotely compact region {} by job {:?} due to {}",
1049 region_id,
1050 job_id,
1051 reason
1052 ))]
1053 RemoteCompaction {
1054 region_id: RegionId,
1055 job_id: Option<JobId>,
1056 reason: String,
1057 #[snafu(implicit)]
1058 location: Location,
1059 },
1060
1061 #[snafu(display("Failed to initialize puffin stager"))]
1062 PuffinInitStager {
1063 source: puffin::error::Error,
1064 #[snafu(implicit)]
1065 location: Location,
1066 },
1067
1068 #[snafu(display("Failed to purge puffin stager"))]
1069 PuffinPurgeStager {
1070 source: puffin::error::Error,
1071 #[snafu(implicit)]
1072 location: Location,
1073 },
1074
1075 #[snafu(display("Failed to build puffin reader"))]
1076 PuffinBuildReader {
1077 source: puffin::error::Error,
1078 #[snafu(implicit)]
1079 location: Location,
1080 },
1081
1082 #[snafu(display("Failed to retrieve index options from column metadata"))]
1083 IndexOptions {
1084 #[snafu(implicit)]
1085 location: Location,
1086 source: datatypes::error::Error,
1087 column_name: String,
1088 },
1089
1090 #[snafu(display("Failed to create fulltext index creator"))]
1091 CreateFulltextCreator {
1092 source: index::fulltext_index::error::Error,
1093 #[snafu(implicit)]
1094 location: Location,
1095 },
1096
1097 #[snafu(display("Failed to cast vector of {from} to {to}"))]
1098 CastVector {
1099 #[snafu(implicit)]
1100 location: Location,
1101 from: ConcreteDataType,
1102 to: ConcreteDataType,
1103 source: datatypes::error::Error,
1104 },
1105
1106 #[snafu(display("Failed to push text to fulltext index"))]
1107 FulltextPushText {
1108 source: index::fulltext_index::error::Error,
1109 #[snafu(implicit)]
1110 location: Location,
1111 },
1112
1113 #[snafu(display("Failed to finalize fulltext index creator"))]
1114 FulltextFinish {
1115 source: index::fulltext_index::error::Error,
1116 #[snafu(implicit)]
1117 location: Location,
1118 },
1119
1120 #[snafu(display("Failed to apply fulltext index"))]
1121 ApplyFulltextIndex {
1122 source: index::fulltext_index::error::Error,
1123 #[snafu(implicit)]
1124 location: Location,
1125 },
1126
1127 #[snafu(display("SST file {} does not contain valid stats info", file_path))]
1128 StatsNotPresent {
1129 file_path: String,
1130 #[snafu(implicit)]
1131 location: Location,
1132 },
1133
1134 #[snafu(display("Failed to decode stats of file {}", file_path))]
1135 DecodeStats {
1136 file_path: String,
1137 #[snafu(implicit)]
1138 location: Location,
1139 },
1140
1141 #[snafu(display("Region {} is busy", region_id))]
1142 RegionBusy {
1143 region_id: RegionId,
1144 #[snafu(implicit)]
1145 location: Location,
1146 },
1147
1148 #[snafu(display("Failed to get schema metadata"))]
1149 GetSchemaMetadata {
1150 source: common_meta::error::Error,
1151 #[snafu(implicit)]
1152 location: Location,
1153 },
1154
1155 #[snafu(display("Timeout"))]
1156 Timeout {
1157 #[snafu(source)]
1158 error: Elapsed,
1159 #[snafu(implicit)]
1160 location: Location,
1161 },
1162
1163 #[snafu(display("Failed to read file metadata"))]
1164 Metadata {
1165 #[snafu(source)]
1166 error: std::io::Error,
1167 #[snafu(implicit)]
1168 location: Location,
1169 },
1170
1171 #[snafu(display("Failed to push value to bloom filter"))]
1172 PushBloomFilterValue {
1173 source: index::bloom_filter::error::Error,
1174 #[snafu(implicit)]
1175 location: Location,
1176 },
1177
1178 #[snafu(display("Failed to finish bloom filter"))]
1179 BloomFilterFinish {
1180 source: index::bloom_filter::error::Error,
1181 #[snafu(implicit)]
1182 location: Location,
1183 },
1184
1185 #[cfg(feature = "vector_index")]
1186 #[snafu(display("Failed to build vector index: {}", reason))]
1187 VectorIndexBuild {
1188 reason: String,
1189 #[snafu(implicit)]
1190 location: Location,
1191 },
1192
1193 #[cfg(feature = "vector_index")]
1194 #[snafu(display("Failed to finish vector index: {}", reason))]
1195 VectorIndexFinish {
1196 reason: String,
1197 #[snafu(implicit)]
1198 location: Location,
1199 },
1200
1201 #[snafu(display("Manual compaction is override by following operations."))]
1202 ManualCompactionOverride {},
1203
1204 #[snafu(display("Manual compaction is already running for region {region_id}."))]
1205 ManualCompactionAlreadyRunning { region_id: RegionId },
1206
1207 #[snafu(display("Compaction is cancelled."))]
1208 CompactionCancelled {},
1209
1210 #[snafu(display("Flush is cancelled."))]
1211 FlushCancelled {},
1212
1213 #[snafu(display("Compaction memory exhausted for region {region_id} (policy: {policy})",))]
1214 CompactionMemoryExhausted {
1215 region_id: RegionId,
1216 policy: String,
1217 #[snafu(source)]
1218 source: common_memory_manager::Error,
1219 #[snafu(implicit)]
1220 location: Location,
1221 },
1222
1223 #[snafu(display(
1224 "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: {}",
1225 global,
1226 region
1227 ))]
1228 IncompatibleWalProviderChange { global: String, region: String },
1229
1230 #[snafu(display("Expected mito manifest info"))]
1231 MitoManifestInfo {
1232 #[snafu(implicit)]
1233 location: Location,
1234 },
1235
1236 #[snafu(display("Failed to scan series"))]
1237 ScanSeries {
1238 #[snafu(implicit)]
1239 location: Location,
1240 source: Arc<Error>,
1241 },
1242
1243 #[snafu(display("Partition {} scan multiple times", partition))]
1244 ScanMultiTimes {
1245 partition: usize,
1246 #[snafu(implicit)]
1247 location: Location,
1248 },
1249
1250 #[snafu(display("Invalid partition expression: {}", expr))]
1251 InvalidPartitionExpr {
1252 expr: String,
1253 #[snafu(implicit)]
1254 location: Location,
1255 source: partition::error::Error,
1256 },
1257
1258 #[snafu(display("Failed to decode bulk wal entry"))]
1259 ConvertBulkWalEntry {
1260 #[snafu(implicit)]
1261 location: Location,
1262 source: common_grpc::Error,
1263 },
1264
1265 #[snafu(display("Failed to encode"))]
1266 Encode {
1267 #[snafu(implicit)]
1268 location: Location,
1269 source: mito_codec::error::Error,
1270 },
1271
1272 #[snafu(display("Failed to decode"))]
1273 Decode {
1274 #[snafu(implicit)]
1275 location: Location,
1276 source: mito_codec::error::Error,
1277 },
1278
1279 #[snafu(display("Unexpected: {reason}"))]
1280 Unexpected {
1281 reason: String,
1282 #[snafu(implicit)]
1283 location: Location,
1284 },
1285
1286 #[cfg(feature = "enterprise")]
1287 #[snafu(display("Failed to scan external range"))]
1288 ScanExternalRange {
1289 source: BoxedError,
1290 #[snafu(implicit)]
1291 location: Location,
1292 },
1293
1294 #[snafu(display(
1295 "Inconsistent timestamp column length, expect: {}, actual: {}",
1296 expected,
1297 actual
1298 ))]
1299 InconsistentTimestampLength {
1300 expected: usize,
1301 actual: usize,
1302 #[snafu(implicit)]
1303 location: Location,
1304 },
1305
1306 #[snafu(display(
1307 "Too many files to read concurrently: {}, max allowed: {}",
1308 actual,
1309 max
1310 ))]
1311 TooManyFilesToRead {
1312 actual: usize,
1313 max: usize,
1314 #[snafu(implicit)]
1315 location: Location,
1316 },
1317
1318 #[snafu(display("Duration out of range: {input:?}"))]
1319 DurationOutOfRange {
1320 input: std::time::Duration,
1321 #[snafu(source)]
1322 error: chrono::OutOfRangeError,
1323 #[snafu(implicit)]
1324 location: Location,
1325 },
1326
1327 #[snafu(display("GC job permit exhausted"))]
1328 TooManyGcJobs {
1329 #[snafu(implicit)]
1330 location: Location,
1331 },
1332
1333 #[snafu(display(
1334 "Staging partition expr mismatch, manifest: {:?}, request: {}",
1335 manifest_expr,
1336 request_expr
1337 ))]
1338 StagingPartitionExprMismatch {
1339 manifest_expr: Option<String>,
1340 request_expr: String,
1341 #[snafu(implicit)]
1342 location: Location,
1343 },
1344
1345 #[snafu(display(
1346 "Invalid source and target region, source: {}, target: {}",
1347 source_region_id,
1348 target_region_id
1349 ))]
1350 InvalidSourceAndTargetRegion {
1351 source_region_id: RegionId,
1352 target_region_id: RegionId,
1353 #[snafu(implicit)]
1354 location: Location,
1355 },
1356
1357 #[snafu(display("Failed to prune file"))]
1358 PruneFile {
1359 source: Arc<Error>,
1360 #[snafu(implicit)]
1361 location: Location,
1362 },
1363
1364 #[snafu(display("Failed to cast column"))]
1365 CastColumn {
1366 #[snafu(source)]
1367 error: datafusion::error::DataFusionError,
1368 #[snafu(implicit)]
1369 location: Location,
1370 },
1371
1372 #[snafu(display("Failed to generate Arrow schema from Parquet file: {}", file))]
1373 ParquetToArrowSchema {
1374 file: String,
1375 #[snafu(source)]
1376 error: parquet::errors::ParquetError,
1377 #[snafu(implicit)]
1378 location: Location,
1379 },
1380
1381 #[snafu(display(
1382 "Region {} is in {:?} state, expect: Writable, Staging or Downgrading",
1383 region_id,
1384 state
1385 ))]
1386 FlushableRegionState {
1387 region_id: RegionId,
1388 state: RegionRoleState,
1389 #[snafu(implicit)]
1390 location: Location,
1391 },
1392}
1393
1394pub type Result<T, E = Error> = std::result::Result<T, E>;
1395
1396impl Error {
1397 pub(crate) fn is_fill_default(&self) -> bool {
1399 matches!(self, Error::FillDefault { .. })
1400 }
1401
1402 pub(crate) fn is_object_not_found(&self) -> bool {
1404 match self {
1405 Error::OpenDal { error, .. } => error.kind() == ErrorKind::NotFound,
1406 Error::ManifestDeltaNotFound { .. } => true,
1407 _ => false,
1408 }
1409 }
1410
1411 pub(crate) fn may_have_persisted_manifest_update(&self) -> bool {
1416 match self {
1417 Error::UpdateManifest { .. }
1418 | Error::RegionState { .. }
1419 | Error::RegionTruncated { .. }
1420 | Error::RegionStopped { .. }
1421 | Error::SerdeJson { .. }
1422 | Error::CompressObject { .. } => false,
1423 Error::OpenDal { error, .. } => !matches!(
1424 error.kind(),
1425 ErrorKind::Unsupported
1426 | ErrorKind::ConfigInvalid
1427 | ErrorKind::NotFound
1428 | ErrorKind::PermissionDenied
1429 | ErrorKind::IsADirectory
1430 | ErrorKind::NotADirectory
1431 | ErrorKind::AlreadyExists
1432 | ErrorKind::RateLimited
1433 | ErrorKind::IsSameFile
1434 | ErrorKind::ConditionNotMatch
1435 | ErrorKind::RangeNotSatisfied
1436 ),
1437 _ => true,
1438 }
1439 }
1440}
1441
1442impl ErrorExt for Error {
1443 fn status_code(&self) -> StatusCode {
1444 use Error::*;
1445
1446 match self {
1447 DataTypeMismatch { source, .. } => source.status_code(),
1448 OpenDal { .. } | ManifestDeltaNotFound { .. } | ReadParquet { .. } => {
1449 StatusCode::StorageUnavailable
1450 }
1451 WriteWal { source, .. } | ReadWal { source, .. } | DeleteWal { source, .. } => {
1452 source.status_code()
1453 }
1454 CompressObject { .. }
1455 | DecompressObject { .. }
1456 | SerdeJson { .. }
1457 | Utf8 { .. }
1458 | NewRecordBatch { .. }
1459 | RegionCorrupted { .. }
1460 | InconsistentFile { .. }
1461 | CreateDefault { .. }
1462 | InvalidParquet { .. }
1463 | OperateAbortedIndex { .. }
1464 | IndexEncodeNull { .. }
1465 | NoCheckpoint { .. }
1466 | NoManifests { .. }
1467 | FilesLost { .. }
1468 | InstallManifestTo { .. }
1469 | Unexpected { .. }
1470 | SerializeColumnMetadata { .. }
1471 | SerializeManifest { .. }
1472 | StagingPartitionExprMismatch { .. } => StatusCode::Unexpected,
1473
1474 RegionNotFound { .. } => StatusCode::RegionNotFound,
1475 ObjectStoreNotFound { .. }
1476 | InvalidScanIndex { .. }
1477 | InvalidMeta { .. }
1478 | InvalidRequest { .. }
1479 | PartitionExprVersionMismatch { .. }
1480 | FillDefault { .. }
1481 | ConvertColumnDataType { .. }
1482 | ColumnNotFound { .. }
1483 | InvalidMetadata { .. }
1484 | InvalidRegionOptions { .. }
1485 | InvalidWalReadRequest { .. }
1486 | PartitionOutOfRange { .. }
1487 | ParseJobId { .. }
1488 | DurationOutOfRange { .. }
1489 | MissingOldManifest { .. }
1490 | MissingNewManifest { .. }
1491 | MissingManifest { .. }
1492 | NoOldManifests { .. }
1493 | MissingPartitionExpr { .. }
1494 | SerializePartitionExpr { .. }
1495 | InvalidSourceAndTargetRegion { .. } => StatusCode::InvalidArguments,
1496
1497 IncrementalQueryStale { .. } | SnapshotFenceStale { .. } => StatusCode::RequestOutdated,
1498
1499 SequenceRangeUnsupported { .. } => StatusCode::Unsupported,
1500
1501 RegionSequenceDomainBroken { .. }
1502 | RegionMetadataNotFound { .. }
1503 | Join { .. }
1504 | WorkerStopped { .. }
1505 | Recv { .. }
1506 | DecodeWal { .. }
1507 | ComputeArrow { .. }
1508 | EvalPartitionFilter { .. }
1509 | MergeCandidateSeries { .. }
1510 | BiErrors { .. }
1511 | StopScheduler { .. }
1512 | ComputeVector { .. }
1513 | EncodeMemtable { .. }
1514 | CreateDir { .. }
1515 | ReadDataPart { .. }
1516 | BuildEntry { .. }
1517 | Metadata { .. }
1518 | CastColumn { .. }
1519 | MitoManifestInfo { .. }
1520 | ParquetToArrowSchema { .. } => StatusCode::Internal,
1521
1522 FetchManifests { source, .. } => source.status_code(),
1523
1524 OpenRegion { source, .. } => source.status_code(),
1525
1526 WriteParquet { .. } => StatusCode::StorageUnavailable,
1527 WriteGroup { source, .. } => source.status_code(),
1528 InvalidBatch { .. } => StatusCode::InvalidArguments,
1529 InvalidRecordBatch { .. } => StatusCode::InvalidArguments,
1530 ConvertVector { source, .. } => source.status_code(),
1531
1532 PrimaryKeyLengthMismatch { .. } => StatusCode::InvalidArguments,
1533 InvalidSender { .. } => StatusCode::InvalidArguments,
1534 InvalidSchedulerState { .. } => StatusCode::InvalidArguments,
1535 RegionRequirement { .. } => StatusCode::InvalidArguments,
1536 DeleteSsts { .. } | DeleteIndex { .. } | DeleteIndexes { .. } => {
1537 StatusCode::StorageUnavailable
1538 }
1539 FlushRegion { source, .. } | BuildIndexAsync { source, .. } => source.status_code(),
1540 RegionDropped { .. } => StatusCode::Cancelled,
1541 RegionClosed { .. } => StatusCode::Cancelled,
1542 StaleCompactionExecution { .. } => StatusCode::Cancelled,
1543 RegionTruncated { .. } => StatusCode::Cancelled,
1544 RejectWrite { .. } => StatusCode::StorageUnavailable,
1545 CompactRegion { source, .. } => source.status_code(),
1546 EditRegion { source, .. } => source.status_code(),
1547 CompatReader { .. } => StatusCode::Unexpected,
1548 InvalidRegionRequest { source, .. } => source.status_code(),
1549 RegionState { .. } | UpdateManifest { .. } => StatusCode::RegionNotReady,
1550 JsonOptions { .. } => StatusCode::InvalidArguments,
1551 EmptyRegionDir { .. } | EmptyManifestDir { .. } => StatusCode::RegionNotFound,
1552 ConvertValue { source, .. } => source.status_code(),
1553 ApplyBloomFilterIndex { source, .. } => source.status_code(),
1554 InvalidPartitionExpr { source, .. } => source.status_code(),
1555 BuildIndexApplier { source, .. }
1556 | PushIndexValue { source, .. }
1557 | ApplyInvertedIndex { source, .. }
1558 | IndexFinish { source, .. } => source.status_code(),
1559 #[cfg(feature = "vector_index")]
1560 ApplyVectorIndex { .. } => StatusCode::Internal,
1561 PuffinReadBlob { source, .. }
1562 | PuffinAddBlob { source, .. }
1563 | PuffinInitStager { source, .. }
1564 | PuffinBuildReader { source, .. }
1565 | PuffinPurgeStager { source, .. } => source.status_code(),
1566 CleanDir { .. } => StatusCode::Unexpected,
1567 InvalidConfig { .. } => StatusCode::InvalidArguments,
1568 StaleLogEntry { .. }
1569 | InvalidNativeHistogramSubfield { .. }
1570 | InvalidNativeHistogramFieldId { .. } => StatusCode::Unexpected,
1571
1572 External { source, .. } => source.status_code(),
1573
1574 RecordBatch { source, .. } => source.status_code(),
1575
1576 Download { .. } | Upload { .. } => StatusCode::StorageUnavailable,
1577 ChecksumMismatch { .. } => StatusCode::Unexpected,
1578 RegionStopped { .. } => StatusCode::RegionNotReady,
1579 TimeRangePredicateOverflow { .. } => StatusCode::InvalidArguments,
1580 UnsupportedOperation { .. } => StatusCode::Unsupported,
1581 RemoteCompaction { .. } => StatusCode::Unexpected,
1582
1583 IndexOptions { source, .. } => source.status_code(),
1584 CreateFulltextCreator { source, .. } => source.status_code(),
1585 CastVector { source, .. } => source.status_code(),
1586 FulltextPushText { source, .. }
1587 | FulltextFinish { source, .. }
1588 | ApplyFulltextIndex { source, .. } => source.status_code(),
1589 DecodeStats { .. } | StatsNotPresent { .. } => StatusCode::Internal,
1590 RegionBusy { .. } => StatusCode::RegionBusy,
1591 GetSchemaMetadata { source, .. } => source.status_code(),
1592 Timeout { .. } => StatusCode::Cancelled,
1593
1594 DecodeArrowRowGroup { .. } => StatusCode::Internal,
1595
1596 PushBloomFilterValue { source, .. } | BloomFilterFinish { source, .. } => {
1597 source.status_code()
1598 }
1599
1600 #[cfg(feature = "vector_index")]
1601 VectorIndexBuild { .. } | VectorIndexFinish { .. } => StatusCode::Internal,
1602
1603 ManualCompactionOverride {} | CompactionCancelled {} | FlushCancelled {} => {
1604 StatusCode::Cancelled
1605 }
1606
1607 ManualCompactionAlreadyRunning { .. } => StatusCode::RegionBusy,
1611
1612 CompactionMemoryExhausted { source, .. } => source.status_code(),
1613
1614 IncompatibleWalProviderChange { .. } => StatusCode::InvalidArguments,
1615
1616 ScanSeries { source, .. } => source.status_code(),
1617
1618 ScanMultiTimes { .. } => StatusCode::InvalidArguments,
1619 ConvertBulkWalEntry { source, .. } => source.status_code(),
1620
1621 Encode { source, .. } | Decode { source, .. } => source.status_code(),
1622
1623 #[cfg(feature = "enterprise")]
1624 ScanExternalRange { source, .. } => source.status_code(),
1625
1626 InconsistentTimestampLength { .. } => StatusCode::InvalidArguments,
1627
1628 TooManyFilesToRead { .. } | TooManyGcJobs { .. } => StatusCode::RateLimited,
1629
1630 PruneFile { source, .. } => source.status_code(),
1631
1632 FlushableRegionState { .. } => StatusCode::RegionNotReady,
1633 }
1634 }
1635
1636 fn as_any(&self) -> &dyn Any {
1637 self
1638 }
1639
1640 fn retry_hint(&self) -> RetryHint {
1641 use Error::*;
1642
1643 match self {
1644 ReadParquet { .. }
1645 | WriteParquet { .. }
1646 | RejectWrite { .. }
1647 | Download { .. }
1648 | Upload { .. }
1649 | RegionState { .. }
1650 | UpdateManifest { .. }
1651 | RegionStopped { .. }
1652 | RegionBusy { .. }
1653 | ManualCompactionAlreadyRunning { .. }
1654 | FlushableRegionState { .. }
1655 | ManifestDeltaNotFound { .. } => RetryHint::Retryable,
1656
1657 OpenDal { error, .. }
1658 | DeleteSsts { error, .. }
1659 | DeleteIndex { error, .. }
1660 | DeleteIndexes { error, .. } => retry_hint_from_opendal_error(error),
1661
1662 WriteWal { source, .. }
1663 | ReadWal { source, .. }
1664 | DeleteWal { source, .. }
1665 | FetchManifests { source, .. }
1666 | External { source, .. } => source.retry_hint(),
1667
1668 OpenRegion { source, .. }
1669 | WriteGroup { source, .. }
1670 | FlushRegion { source, .. }
1671 | BuildIndexAsync { source, .. }
1672 | CompactRegion { source, .. }
1673 | EditRegion { source, .. }
1674 | ScanSeries { source, .. }
1675 | PruneFile { source, .. } => source.retry_hint(),
1676
1677 DataTypeMismatch { source, .. }
1678 | ConvertVector { source, .. }
1679 | ConvertValue { source, .. }
1680 | IndexOptions { source, .. }
1681 | CastVector { source, .. } => source.retry_hint(),
1682
1683 BuildIndexApplier { source, .. }
1684 | PushIndexValue { source, .. }
1685 | ApplyInvertedIndex { source, .. }
1686 | IndexFinish { source, .. } => source.retry_hint(),
1687
1688 ApplyBloomFilterIndex { source, .. }
1689 | PushBloomFilterValue { source, .. }
1690 | BloomFilterFinish { source, .. } => source.retry_hint(),
1691
1692 PuffinReadBlob { source, .. }
1693 | PuffinAddBlob { source, .. }
1694 | PuffinInitStager { source, .. }
1695 | PuffinBuildReader { source, .. }
1696 | PuffinPurgeStager { source, .. } => source.retry_hint(),
1697
1698 CreateFulltextCreator { source, .. }
1699 | FulltextPushText { source, .. }
1700 | FulltextFinish { source, .. }
1701 | ApplyFulltextIndex { source, .. } => source.retry_hint(),
1702
1703 InvalidRegionRequest { source, .. } => source.retry_hint(),
1704 InvalidPartitionExpr { source, .. } => source.retry_hint(),
1705 RecordBatch { source, .. } => source.retry_hint(),
1706 GetSchemaMetadata { source, .. } => source.retry_hint(),
1707 CompactionMemoryExhausted { source, .. } => source.retry_hint(),
1708 ConvertBulkWalEntry { source, .. } => source.retry_hint(),
1709 Encode { source, .. } | Decode { source, .. } => source.retry_hint(),
1710
1711 #[cfg(feature = "enterprise")]
1712 ScanExternalRange { source, .. } => source.retry_hint(),
1713
1714 _ => RetryHint::NonRetryable,
1715 }
1716 }
1717}
1718
1719#[cfg(test)]
1720mod tests {
1721 use snafu::IntoError;
1722
1723 use super::*;
1724
1725 #[test]
1726 fn test_manifest_update_persistence() {
1727 let rejected_kinds = [
1728 ErrorKind::Unsupported,
1729 ErrorKind::ConfigInvalid,
1730 ErrorKind::NotFound,
1731 ErrorKind::PermissionDenied,
1732 ErrorKind::IsADirectory,
1733 ErrorKind::NotADirectory,
1734 ErrorKind::AlreadyExists,
1735 ErrorKind::RateLimited,
1736 ErrorKind::IsSameFile,
1737 ErrorKind::ConditionNotMatch,
1738 ErrorKind::RangeNotSatisfied,
1739 ];
1740 for kind in rejected_kinds {
1741 let error = OpenDalSnafu {}.into_error(object_store::Error::new(kind, "test"));
1742 assert!(
1743 !error.may_have_persisted_manifest_update(),
1744 "error kind {kind:?} should prove the manifest was not persisted"
1745 );
1746 }
1747
1748 let error =
1749 OpenDalSnafu {}.into_error(object_store::Error::new(ErrorKind::Unexpected, "test"));
1750 assert!(error.may_have_persisted_manifest_update());
1751
1752 let region_id = RegionId::new(1, 1);
1753 let error = RegionTruncatedSnafu { region_id }.build();
1754 assert!(!error.may_have_persisted_manifest_update());
1755
1756 let error = RegionMetadataNotFoundSnafu {}.build();
1758 assert!(error.may_have_persisted_manifest_update());
1759 }
1760}