use std::{io, path::PathBuf};
use thiserror::Error as ThisError;
#[derive(Debug, ThisError)]
pub enum CacheFileError {
#[error("failed to create cache directory at {}: {source}", path.display())]
CreateDirectory {
path: PathBuf,
source: io::Error,
},
#[error("failed to create refresh lock at {}: {source}", path.display())]
CreateRefreshLock {
path: PathBuf,
source: io::Error,
},
#[error("failed to read refresh lock at {}: {source}", path.display())]
ReadRefreshLock {
path: PathBuf,
source: io::Error,
},
#[error(
"failed to parse refresh lock at {}; remove the lock manually after verifying no refresh is running: {source}",
path.display()
)]
ParseRefreshLock {
path: PathBuf,
source: serde_json::Error,
},
#[error(
"invalid refresh lock at {}; remove the lock manually after verifying no refresh is running: {reason}",
path.display()
)]
InvalidRefreshLock {
path: PathBuf,
reason: String,
},
#[error("failed to serialize refresh lock at {}: {source}", path.display())]
SerializeRefreshLock {
path: PathBuf,
source: serde_json::Error,
},
#[error("failed to write refresh lock at {}: {source}", path.display())]
WriteRefreshLock {
path: PathBuf,
source: io::Error,
},
#[error("failed to remove refresh lock at {}: {source}", path.display())]
RemoveRefreshLock {
path: PathBuf,
source: io::Error,
},
#[error("refresh already in progress; lock exists at {} since unix_ms={started_at_unix_ms}", path.display())]
RefreshAlreadyInProgress {
path: PathBuf,
started_at_unix_ms: u64,
},
#[error(
"stale refresh lock exists at {} since unix_ms={started_at_unix_ms}; remove it manually after verifying no refresh is running",
path.display()
)]
StaleRefreshLock {
path: PathBuf,
started_at_unix_ms: u64,
},
#[error("failed to write cache temp file at {}: {source}", path.display())]
WriteTemp {
path: PathBuf,
source: io::Error,
},
#[error("failed to sync cache temp file at {}: {source}", path.display())]
SyncTemp {
path: PathBuf,
source: io::Error,
},
#[error("failed to replace cache at {} from {}: {source}", target_path.display(), temp_path.display())]
Replace {
temp_path: PathBuf,
target_path: PathBuf,
source: io::Error,
},
#[error("failed to sync cache directory at {}: {source}", path.display())]
SyncDirectory {
path: PathBuf,
source: io::Error,
},
#[error("failed to write cache output at {}: {source}", path.display())]
WriteOutput {
path: PathBuf,
source: io::Error,
},
#[error("failed to sync cache output at {}: {source}", path.display())]
SyncOutput {
path: PathBuf,
source: io::Error,
},
}
#[derive(Debug, ThisError)]
pub enum HostCacheError {
#[error("{component} cache is missing at {}", path.display())]
MissingCache {
component: &'static str,
path: PathBuf,
},
#[error("failed to read {component} cache at {}: {source}", path.display())]
ReadCache {
component: &'static str,
path: PathBuf,
source: io::Error,
},
#[error("failed to parse {component} cache at {}: {source}", path.display())]
ParseCache {
component: &'static str,
path: PathBuf,
source: serde_json::Error,
},
#[error("failed to serialize {component} cache JSON for {}: {source}", path.display())]
SerializeCache {
component: &'static str,
path: PathBuf,
source: serde_json::Error,
},
#[error("unsupported {component} cache schema version {version}; expected {expected}")]
UnsupportedCacheSchemaVersion {
component: &'static str,
version: u32,
expected: u32,
},
#[error("cached {component} network mismatch: path is for {requested}, report is for {actual}")]
NetworkMismatch {
component: &'static str,
requested: String,
actual: String,
},
#[error("{component} cache operation failed: {source}")]
Operation {
component: &'static str,
#[source]
source: CacheFileError,
},
}
impl HostCacheError {
#[must_use]
pub const fn missing_cache(component: &'static str, path: PathBuf) -> Self {
Self::MissingCache { component, path }
}
#[must_use]
pub const fn read_cache(component: &'static str, path: PathBuf, source: io::Error) -> Self {
Self::ReadCache {
component,
path,
source,
}
}
#[must_use]
pub const fn parse_cache(
component: &'static str,
path: PathBuf,
source: serde_json::Error,
) -> Self {
Self::ParseCache {
component,
path,
source,
}
}
#[must_use]
pub const fn serialize_cache(
component: &'static str,
path: PathBuf,
source: serde_json::Error,
) -> Self {
Self::SerializeCache {
component,
path,
source,
}
}
#[must_use]
pub const fn unsupported_cache_schema_version(
component: &'static str,
version: u32,
expected: u32,
) -> Self {
Self::UnsupportedCacheSchemaVersion {
component,
version,
expected,
}
}
#[must_use]
pub const fn network_mismatch(
component: &'static str,
requested: String,
actual: String,
) -> Self {
Self::NetworkMismatch {
component,
requested,
actual,
}
}
#[must_use]
pub const fn operation(component: &'static str, source: CacheFileError) -> Self {
Self::Operation { component, source }
}
}