soma_self_update/
error.rs1use std::path::PathBuf;
2
3#[derive(Debug, thiserror::Error)]
5pub enum UpdateError {
6 #[error("invalid update directive: {0}")]
7 InvalidDirective(&'static str),
8 #[error("invalid SHA-256 digest: {0}")]
9 InvalidDigest(String),
10 #[error("invalid update policy: {0}")]
11 InvalidPolicy(&'static str),
12 #[error("invalid base URL {url}: {message}")]
13 InvalidBaseUrl { url: String, message: String },
14 #[error("invalid artifact URL {url}: {message}")]
15 InvalidArtifactUrl { url: String, message: String },
16 #[error("artifact URL crosses origins from {base} to {artifact}")]
17 CrossOriginArtifact { base: String, artifact: String },
18 #[error("artifact transport is not permitted: {0}")]
19 InsecureTransport(String),
20 #[error("artifact exceeds {limit} byte limit (received at least {actual})")]
21 ArtifactTooLarge { limit: u64, actual: u64 },
22 #[error("artifact digest mismatch: expected {expected}, got {actual}")]
23 DigestMismatch { expected: String, actual: String },
24 #[error("validator timed out after {timeout:?}")]
25 ValidationTimedOut { timeout: std::time::Duration },
26 #[error("validator exited unsuccessfully (code {code:?}): {stderr}")]
27 ValidationFailed { code: Option<i32>, stderr: String },
28 #[error("validator output is not valid UTF-8")]
29 InvalidVersionOutput,
30 #[error("validator {stream} exceeded the {limit} byte output limit")]
31 ValidationOutputTooLarge { stream: &'static str, limit: usize },
32 #[error("validator output did not contain exact version {expected}: {output}")]
33 VersionMismatch { expected: String, output: String },
34 #[error("another update transaction holds lock {path}")]
35 UpdateInProgress { path: PathBuf },
36 #[error("invalid update marker {path}: {message}")]
37 InvalidMarker { path: PathBuf, message: String },
38 #[error("rollback backup is missing: {path}")]
39 MissingRollback { path: PathBuf },
40 #[error("running version {running} does not match pending target {target}")]
41 RunningVersionMismatch { running: String, target: String },
42 #[error("the provided installer is unsupported on this platform")]
43 UnsupportedPlatform,
44 #[error("update layout paths collide: {first} and {second}")]
45 InvalidLayout { first: PathBuf, second: PathBuf },
46 #[error("an update to {target} is already pending at {path}")]
47 PendingUpdateExists { path: PathBuf, target: String },
48 #[error("state authority migration is blocked by transaction state at {path}: {message}")]
49 StateMigrationBlocked { path: PathBuf, message: String },
50 #[error("staged artifact is not a regular file: {path}")]
51 InvalidStagedArtifact { path: PathBuf },
52 #[error("staged artifact identity changed after validation: {path}")]
53 ArtifactIdentityChanged { path: PathBuf },
54 #[error("executable identity or mode changed after staging: {path}")]
55 ExecutableIdentityChanged { path: PathBuf },
56 #[error("unsafe executable mode {mode:#06o} for {path}: {remediation}")]
57 UnsafeExecutableMode {
58 path: PathBuf,
59 mode: u32,
60 remediation: &'static str,
61 },
62 #[error("staging failed for {path}: {operation}; cleanup also failed: {cleanup}")]
63 ArtifactCleanupFailed {
64 path: PathBuf,
65 operation: Box<UpdateError>,
66 cleanup: std::io::Error,
67 },
68 #[error("update operation failed: {operation}; transaction cleanup also failed: {cleanup}")]
69 TransactionCleanupFailed {
70 operation: Box<UpdateError>,
71 cleanup: Box<UpdateError>,
72 },
73 #[error("I/O operation failed for {path}: {source}")]
74 Io {
75 path: PathBuf,
76 #[source]
77 source: std::io::Error,
78 },
79}
80
81impl UpdateError {
82 pub(crate) fn io(path: impl Into<PathBuf>, source: std::io::Error) -> Self {
83 Self::Io {
84 path: path.into(),
85 source,
86 }
87 }
88}
89
90pub type Result<T> = std::result::Result<T, UpdateError>;