Skip to main content

hdiff_update_core/
error.rs

1use 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}