hdiff_update_core/
error.rs1use std::{path::PathBuf, process::ExitStatus};
2
3use thiserror::Error;
4
5#[derive(Debug, Error)]
6pub enum Error {
7 #[error("I/O error at {path}: {source}")]
8 IoWithPath {
9 path: PathBuf,
10 #[source]
11 source: std::io::Error,
12 },
13 #[error("I/O error: {0}")]
14 Io(#[from] std::io::Error),
15 #[error("HTTP error: {0}")]
16 Http(#[from] reqwest::Error),
17 #[error("unexpected HTTP status: {status}")]
18 UnexpectedHttpStatus { status: u16 },
19 #[error("URL error: {0}")]
20 Url(#[from] url::ParseError),
21 #[error("JSON error: {0}")]
22 Json(#[from] serde_json::Error),
23 #[error("tool not found: {tool}")]
24 ToolNotFound { tool: String },
25 #[error("process failed: {program} {args:?}, status={status}, stderr={stderr}")]
26 ProcessFailed {
27 program: PathBuf,
28 args: Vec<String>,
29 status: ExitStatus,
30 stdout: String,
31 stderr: String,
32 },
33 #[error("SHA-256 mismatch for {path}: expected {expected}, got {actual}")]
34 HashMismatch {
35 path: PathBuf,
36 expected: String,
37 actual: String,
38 },
39 #[error("size mismatch for {path}: expected {expected}, got {actual}")]
40 SizeMismatch {
41 path: PathBuf,
42 expected: u64,
43 actual: u64,
44 },
45 #[error("download exceeded byte limit: limit={limit}, attempted={attempted}")]
46 DownloadLimitExceeded { limit: u64, attempted: u64 },
47 #[error(
48 "insufficient disk space at {path}: required={required} bytes, available={available} bytes"
49 )]
50 InsufficientDiskSpace {
51 path: PathBuf,
52 required: u64,
53 available: u64,
54 },
55 #[error("update manifest signature is required but missing")]
56 SignatureMissing,
57 #[error("update manifest signature public key is required")]
58 SignaturePublicKeyMissing,
59 #[error("update manifest signature verification failed")]
60 SignatureVerificationFailed,
61 #[error("invalid {kind}: {message}")]
62 InvalidKeyMaterial { kind: String, message: String },
63 #[error("unsupported patch algorithm: {0}")]
64 UnsupportedAlgorithm(String),
65 #[error("unexpected update version: expected {expected}, got {actual}")]
66 UnexpectedVersion { expected: String, actual: String },
67 #[error("invalid semantic version {value}: {message}")]
68 InvalidVersion { value: String, message: String },
69 #[error("target version must be newer than current: current={current}, target={target}")]
70 NonUpgradeVersion { current: String, target: String },
71 #[error("manifest has no platform entry for {platform}")]
72 MissingPlatform { platform: String },
73 #[error(
74 "no matching directory delta for platform={platform}, current_version={current_version}"
75 )]
76 NoMatchingDelta {
77 platform: String,
78 current_version: String,
79 },
80 #[error("unsupported URL or path: {0}")]
81 UnsupportedUrl(String),
82 #[error("{label} must use HTTPS in production, got {scheme}")]
83 InsecureTransport { label: String, scheme: String },
84 #[error("{0}")]
85 Message(String),
86}
87
88pub type Result<T> = std::result::Result<T, Error>;
89
90pub(crate) fn io_path(path: impl Into<PathBuf>, source: std::io::Error) -> Error {
91 Error::IoWithPath {
92 path: path.into(),
93 source,
94 }
95}