canic_backup/persistence/
error.rs1use crate::{
8 artifacts::ArtifactChecksumError,
9 execution::BackupExecutionJournalError,
10 journal::{ArtifactState, JournalValidationError},
11 manifest::ManifestValidationError,
12 plan::BackupPlanError,
13};
14
15use std::io;
16
17use thiserror::Error as ThisError;
18
19#[derive(Debug, ThisError)]
27pub enum PersistenceError {
28 #[error("restore reference conflicts with retained recovery authority: {path}")]
29 RestoreReferenceConflict { path: String },
30
31 #[error("invalid restore reference record: {path}")]
32 InvalidRestoreReferences { path: String },
33
34 #[error(transparent)]
36 ArtifactCommit(#[from] ic_backup::ops::persistence::PersistenceError),
37
38 #[error("artifact path escapes backup root: {artifact_path}")]
39 ArtifactPathEscapesBackup { artifact_path: String },
40
41 #[error("manifest backup id {manifest} does not match journal backup id {journal}")]
42 BackupIdMismatch { manifest: String, journal: String },
43
44 #[error(transparent)]
45 Checksum(#[from] ArtifactChecksumError),
46
47 #[error("backup execution operation {sequence} is {state} but has no matching receipt")]
48 ExecutionOperationMissingReceipt { sequence: usize, state: String },
49
50 #[error("backup execution operation {sequence} timestamp does not match latest receipt")]
51 ExecutionOperationReceiptTimestampMismatch { sequence: usize },
52
53 #[error(transparent)]
54 InvalidBackupPlan(#[from] BackupPlanError),
55
56 #[error(transparent)]
57 InvalidExecutionJournal(#[from] BackupExecutionJournalError),
58
59 #[error(transparent)]
60 InvalidJournal(#[from] JournalValidationError),
61
62 #[error(transparent)]
63 InvalidManifest(#[from] ManifestValidationError),
64
65 #[error(transparent)]
66 Io(#[from] io::Error),
67
68 #[error(transparent)]
69 Json(#[from] serde_json::Error),
70
71 #[error("manifest topology receipt {field} does not match journal topology receipt")]
72 ManifestJournalTopologyReceiptMismatch {
73 field: String,
74 manifest: String,
75 journal: String,
76 },
77
78 #[error("backup manifest conflicts with the existing canonical manifest: {path}")]
79 ManifestConflict { path: String },
80
81 #[error(
82 "manifest artifact path for {canister_id} snapshot {snapshot_id} does not match journal artifact path"
83 )]
84 ManifestJournalArtifactPathMismatch {
85 canister_id: String,
86 snapshot_id: String,
87 manifest: String,
88 journal: String,
89 },
90
91 #[error(
92 "manifest checksum for {canister_id} snapshot {snapshot_id} does not match journal checksum"
93 )]
94 ManifestJournalChecksumMismatch {
95 canister_id: String,
96 snapshot_id: String,
97 manifest: String,
98 journal: String,
99 },
100
101 #[error("artifact path does not exist: {0}")]
102 MissingArtifact(String),
103
104 #[error("manifest member {canister_id} snapshot {snapshot_id} has no journal artifact")]
105 MissingJournalArtifact {
106 canister_id: String,
107 snapshot_id: String,
108 },
109
110 #[error("journal artifact {canister_id} snapshot {snapshot_id} has no checksum")]
111 MissingJournalArtifactChecksum {
112 canister_id: String,
113 snapshot_id: String,
114 },
115
116 #[error(
117 "journal artifact {canister_id} snapshot {snapshot_id} must be checksum verified before durable publication; found {state:?}"
118 )]
119 ArtifactNotChecksumVerified {
120 canister_id: String,
121 snapshot_id: String,
122 state: ArtifactState,
123 },
124
125 #[error("journal artifact {canister_id} snapshot {snapshot_id} is not durable")]
126 NonDurableArtifact {
127 canister_id: String,
128 snapshot_id: String,
129 },
130
131 #[error("backup plan {field} does not match execution journal")]
132 PlanJournalMismatch {
133 field: &'static str,
134 plan: String,
135 journal: String,
136 },
137
138 #[error("backup plan operation {sequence} {field} does not match execution journal")]
139 PlanJournalOperationMismatch {
140 sequence: usize,
141 field: &'static str,
142 plan: String,
143 journal: String,
144 },
145
146 #[error("journal artifact {canister_id} snapshot {snapshot_id} is not declared in manifest")]
147 UnexpectedJournalArtifact {
148 canister_id: String,
149 snapshot_id: String,
150 },
151}