Skip to main content

canic_backup/manifest/
error.rs

1//! Module: manifest::error
2//!
3//! Responsibility: report typed backup manifest validation failures.
4//! Does not own: validation traversal, manifest data, or restore execution.
5//! Boundary: shared error contract for manifest readers and validators.
6
7use thiserror::Error as ThisError;
8
9///
10/// ManifestValidationError
11///
12/// Typed validation failure for backup manifest contracts.
13/// Owned by backup manifest validation and returned to callers before restore.
14///
15
16#[derive(Debug, ThisError)]
17pub enum ManifestValidationError {
18    #[error("unsupported manifest version {0}")]
19    UnsupportedManifestVersion(u16),
20
21    #[error("field {0} must not be empty")]
22    EmptyField(&'static str),
23
24    #[error("collection {0} must not be empty")]
25    EmptyCollection(&'static str),
26
27    #[error("field {field} must be a valid principal: {value}")]
28    InvalidPrincipal { field: &'static str, value: String },
29
30    #[error("field {0} must be a non-empty sha256 hex string")]
31    InvalidHash(&'static str),
32
33    #[error("unsupported hash algorithm {0}")]
34    UnsupportedHashAlgorithm(String),
35
36    #[error("unsupported verification kind {0}")]
37    UnsupportedVerificationKind(String),
38
39    #[error("topology hash mismatch between discovery {discovery} and pre-snapshot {pre_snapshot}")]
40    TopologyHashMismatch {
41        discovery: String,
42        pre_snapshot: String,
43    },
44
45    #[error("accepted topology hash {accepted} does not match discovery hash {discovery}")]
46    AcceptedTopologyHashMismatch { accepted: String, discovery: String },
47
48    #[error("duplicate canister id {0}")]
49    DuplicateCanisterId(String),
50
51    #[error("duplicate backup unit id {0}")]
52    DuplicateBackupUnitId(String),
53
54    #[error("backup unit {unit_id} repeats role {role}")]
55    DuplicateBackupUnitRole { unit_id: String, role: String },
56
57    #[error("deployment member {0} has no concrete verification checks")]
58    MissingMemberVerificationChecks(String),
59
60    #[error("backup unit {unit_id} references unknown role {role}")]
61    UnknownBackupUnitRole { unit_id: String, role: String },
62
63    #[error("deployment role {role} is not covered by any backup unit")]
64    BackupUnitCoverageMissingRole { role: String },
65
66    #[error("verification plan references unknown role {role}")]
67    UnknownVerificationRole { role: String },
68
69    #[error("duplicate member verification role {0}")]
70    DuplicateMemberVerificationRole(String),
71
72    #[error("verification check {kind} repeats role {role}")]
73    DuplicateVerificationCheckRole { kind: String, role: String },
74
75    #[error("subtree backup unit {unit_id} is not connected")]
76    SubtreeBackupUnitNotConnected { unit_id: String },
77
78    #[error(
79        "subtree backup unit {unit_id} includes parent {parent} but omits descendant {descendant}"
80    )]
81    SubtreeBackupUnitMissingDescendant {
82        unit_id: String,
83        parent: String,
84        descendant: String,
85    },
86}