Skip to main content

loonfs_core/checkpoint/
error.rs

1//! Manifest load errors, classified as corruption versus store trouble.
2
3use loonfs_api::wire::manifest::MetadataTableFamily;
4use loonfs_api::{ManifestId, ManifestObjectId, NamespaceId};
5use serde::{Deserialize, Serialize};
6use thiserror::Error;
7
8/// Coarse failure class of a manifest load: corruption versus store trouble.
9///
10/// Deliberately not named `*ErrorKind` to avoid colliding with the wire-level
11/// caller-action concept in [`loonfs_api::ErrorKind`].
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
13pub enum ManifestLoadFailureClass {
14    Corrupt,
15    Store,
16}
17
18#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Error)]
19pub enum ManifestLoadError {
20    #[error("missing namespace manifest `{object_key}`")]
21    MissingManifest { object_key: String },
22    #[error("failed to read namespace manifest `{object_key}`: {message}")]
23    ReadManifest { object_key: String, message: String },
24    #[error("namespace manifest codec error for `{object_key}`: {message}")]
25    ManifestCodec { object_key: String, message: String },
26    #[error(
27        "namespace manifest namespace mismatch for `{object_key}`: expected `{expected}`, actual `{actual}`"
28    )]
29    ManifestNamespaceMismatch {
30        object_key: String,
31        expected: NamespaceId,
32        actual: NamespaceId,
33    },
34    #[error(
35        "namespace manifest id mismatch for `{object_key}`: expected `{expected}`, actual `{actual}`"
36    )]
37    ManifestIdMismatch {
38        object_key: String,
39        expected: ManifestId,
40        actual: ManifestId,
41    },
42    #[error(
43        "namespace manifest object id mismatch for `{object_key}`: expected `{expected}`, actual `{actual}`"
44    )]
45    ManifestObjectIdMismatch {
46        object_key: String,
47        expected: ManifestObjectId,
48        actual: ManifestObjectId,
49    },
50    #[error(
51        "namespace manifest conflict for `{object_key}` manifest `{manifest_id}`: expected payload checksum `{expected_payload_checksum}`, actual `{actual_payload_checksum}`"
52    )]
53    ManifestConflict {
54        object_key: String,
55        manifest_id: ManifestId,
56        expected_payload_checksum: String,
57        actual_payload_checksum: String,
58    },
59    #[error("namespace manifest `{object_key}` is missing table family `{family:?}`")]
60    MissingTableFamily {
61        object_key: String,
62        family: MetadataTableFamily,
63    },
64    #[error("namespace manifest `{object_key}` repeats table family `{family:?}`")]
65    DuplicateTableFamily {
66        object_key: String,
67        family: MetadataTableFamily,
68    },
69    #[error("namespace manifest `{object_key}` has invalid runs: {message}")]
70    RunManifestMismatch { object_key: String, message: String },
71    #[error("missing metadata SST `{object_key}`")]
72    MissingSegment { object_key: String },
73    #[error("failed to read metadata SST `{object_key}`: {message}")]
74    ReadSegment { object_key: String, message: String },
75    #[error("metadata SST codec error for `{object_key}`: {message}")]
76    SegmentCodec { object_key: String, message: String },
77    #[error("metadata SST key mismatch for `{object_key}`: expected `{expected}`")]
78    SegmentObjectKeyMismatch {
79        object_key: String,
80        expected: String,
81    },
82    #[error("metadata SST descriptor mismatch for `{object_key}`: {message}")]
83    SegmentDescriptorMismatch { object_key: String, message: String },
84    #[error(
85        "metadata row kind mismatch for `{object_key}` family `{family:?}`: found `{row_kind}`"
86    )]
87    TableRowKindMismatch {
88        object_key: String,
89        family: MetadataTableFamily,
90        row_kind: String,
91    },
92    #[error(
93        "namespace manifest `{object_key}` has duplicate revision rows in `{family:?}` for key `{row_key}`"
94    )]
95    DuplicateRevisionRow {
96        object_key: String,
97        family: MetadataTableFamily,
98        row_key: String,
99    },
100    #[error("namespace manifest `{object_key}` revision index does not match canonical revisions")]
101    RevisionIndexMismatch { object_key: String },
102}
103
104impl ManifestLoadError {
105    pub fn failure_class(&self) -> ManifestLoadFailureClass {
106        match self {
107            Self::ReadManifest { .. }
108            | Self::ReadSegment { .. }
109            | Self::ManifestConflict { .. } => ManifestLoadFailureClass::Store,
110            _ => ManifestLoadFailureClass::Corrupt,
111        }
112    }
113}