1use std::sync::Arc;
4
5#[derive(Debug, thiserror::Error, miette::Diagnostic, Clone)]
12#[non_exhaustive]
13pub enum UpdateError {
14 #[error(transparent)]
16 #[diagnostic(transparent)]
17 Provider(#[from] rtb_forge::ProviderError),
18
19 #[error("no asset found for target {target}")]
21 #[diagnostic(
22 code(rtb::update::no_matching_asset),
23 help("the release exists but has no asset for this platform; a rebuild may be needed")
24 )]
25 NoMatchingAsset {
26 target: String,
28 },
29
30 #[error("asset signature file missing (expected `{asset}.sig` or `{asset}.minisig`)")]
32 #[diagnostic(
33 code(rtb::update::missing_signature),
34 help(
35 "every published release must ship a detached signature; re-run the release pipeline"
36 )
37 )]
38 MissingSignature {
39 asset: String,
41 },
42
43 #[error("signature verification failed for `{asset}`")]
45 #[diagnostic(
46 code(rtb::update::bad_signature),
47 help(
48 "the downloaded bytes do not match the vendor's public key — treat as a potential tampering event"
49 )
50 )]
51 BadSignature {
52 asset: String,
54 },
55
56 #[error("SHA-256 checksum mismatch for `{asset}`")]
58 #[diagnostic(code(rtb::update::bad_checksum))]
59 BadChecksum {
60 asset: String,
62 },
63
64 #[error("downloaded binary failed the runnable-self-test")]
67 #[diagnostic(
68 code(rtb::update::self_test_failed),
69 help("the new binary refused `--version`; refusing to swap")
70 )]
71 SelfTestFailed,
72
73 #[error("atomic swap failed: {0}")]
75 #[diagnostic(code(rtb::update::swap_failed))]
76 SwapFailed(String),
77
78 #[error("tool metadata carries no release source; update disabled")]
81 #[diagnostic(code(rtb::update::no_source))]
82 NoReleaseSource,
83
84 #[error("tool metadata carries no public key; signatures cannot be verified")]
87 #[diagnostic(
88 code(rtb::update::no_public_key),
89 help("populate `ToolMetadata::update_public_keys` at compile time")
90 )]
91 NoPublicKey,
92
93 #[error("downgrade refused: target {target} is older than current {current}")]
97 #[diagnostic(
98 code(rtb::update::downgrade_refused),
99 help("pass `--force` to explicitly downgrade")
100 )]
101 DowngradeRefused {
102 target: semver::Version,
104 current: semver::Version,
106 },
107
108 #[error("archive extraction failed: {0}")]
110 #[diagnostic(code(rtb::update::archive))]
111 Archive(String),
112
113 #[error("asset pattern invalid or unmatched: {0}")]
116 #[diagnostic(code(rtb::update::pattern))]
117 Pattern(String),
118
119 #[error("I/O error: {0}")]
121 #[diagnostic(code(rtb::update::io))]
122 Io(#[from] Arc<std::io::Error>),
123}
124
125impl From<std::io::Error> for UpdateError {
126 fn from(err: std::io::Error) -> Self {
127 Self::Io(Arc::new(err))
128 }
129}
130
131pub type Result<T> = std::result::Result<T, UpdateError>;