canic_backup/persistence/
error.rs1use crate::{
8 artifacts::ArtifactChecksumError, execution::BackupExecutionJournalError,
9 journal::JournalValidationError, manifest::ManifestValidationError, plan::BackupPlanError,
10};
11
12use std::io;
13
14use thiserror::Error as ThisError;
15
16#[derive(Debug, ThisError)]
24pub enum PersistenceError {
25 #[error("artifact path escapes backup root: {artifact_path}")]
26 ArtifactPathEscapesBackup { artifact_path: String },
27
28 #[error("manifest backup id {manifest} does not match journal backup id {journal}")]
29 BackupIdMismatch { manifest: String, journal: String },
30
31 #[error(transparent)]
32 Checksum(#[from] ArtifactChecksumError),
33
34 #[error("backup execution operation {sequence} is {state} but has no matching receipt")]
35 ExecutionOperationMissingReceipt { sequence: usize, state: String },
36
37 #[error("backup execution operation {sequence} timestamp does not match latest receipt")]
38 ExecutionOperationReceiptTimestampMismatch { sequence: usize },
39
40 #[error(transparent)]
41 InvalidBackupPlan(#[from] BackupPlanError),
42
43 #[error(transparent)]
44 InvalidExecutionJournal(#[from] BackupExecutionJournalError),
45
46 #[error(transparent)]
47 InvalidJournal(#[from] JournalValidationError),
48
49 #[error(transparent)]
50 InvalidManifest(#[from] ManifestValidationError),
51
52 #[error(transparent)]
53 Io(#[from] io::Error),
54
55 #[error(transparent)]
56 Json(#[from] serde_json::Error),
57
58 #[error("manifest topology receipt {field} does not match journal topology receipt")]
59 ManifestJournalTopologyReceiptMismatch {
60 field: String,
61 manifest: String,
62 journal: Option<String>,
63 },
64
65 #[error(
66 "manifest artifact path for {canister_id} snapshot {snapshot_id} does not match journal artifact path"
67 )]
68 ManifestJournalArtifactPathMismatch {
69 canister_id: String,
70 snapshot_id: String,
71 manifest: String,
72 journal: String,
73 },
74
75 #[error(
76 "manifest checksum for {canister_id} snapshot {snapshot_id} does not match journal checksum"
77 )]
78 ManifestJournalChecksumMismatch {
79 canister_id: String,
80 snapshot_id: String,
81 manifest: String,
82 journal: String,
83 },
84
85 #[error("artifact path does not exist: {0}")]
86 MissingArtifact(String),
87
88 #[error("manifest member {canister_id} snapshot {snapshot_id} has no journal artifact")]
89 MissingJournalArtifact {
90 canister_id: String,
91 snapshot_id: String,
92 },
93
94 #[error("journal artifact {canister_id} snapshot {snapshot_id} has no checksum")]
95 MissingJournalArtifactChecksum {
96 canister_id: String,
97 snapshot_id: String,
98 },
99
100 #[error("journal artifact {canister_id} snapshot {snapshot_id} is not durable")]
101 NonDurableArtifact {
102 canister_id: String,
103 snapshot_id: String,
104 },
105
106 #[error("backup plan {field} does not match execution journal")]
107 PlanJournalMismatch {
108 field: &'static str,
109 plan: String,
110 journal: String,
111 },
112
113 #[error("backup plan operation {sequence} {field} does not match execution journal")]
114 PlanJournalOperationMismatch {
115 sequence: usize,
116 field: &'static str,
117 plan: String,
118 journal: String,
119 },
120
121 #[error("journal artifact {canister_id} snapshot {snapshot_id} is not declared in manifest")]
122 UnexpectedJournalArtifact {
123 canister_id: String,
124 snapshot_id: String,
125 },
126}