use derive_more::Display;
use foundation_errstacks::ErrorTrace;
pub type DockerResult<T> = Result<T, ErrorTrace<DockerError>>;
#[derive(Debug, Display)]
pub enum DockerError {
#[display("Docker daemon not reachable: {_0}")]
Connection(String),
#[display("Image pull failed for '{image}': {reason}")]
ImagePull { image: String, reason: String },
#[display("Image build failed: {_0}")]
ImageBuild(String),
#[display("Container creation failed: {_0}")]
ContainerCreate(String),
#[display("Container start failed: {_0}")]
ContainerStart(String),
#[display("Container exited with code {code} before becoming ready")]
ContainerExited { code: i64 },
#[display("Wait strategy '{strategy}' timed out after {elapsed:?}")]
WaitTimeout {
strategy: String,
elapsed: std::time::Duration,
},
#[display("Network operation failed: {_0}")]
Network(String),
#[display("Invalid configuration: {_0}")]
InvalidConfig(String),
}
impl std::error::Error for DockerError {}
impl DockerError {
#[must_use]
pub fn is_connection_error(&self) -> bool {
matches!(self, Self::Connection(_))
}
}
#[must_use]
pub fn docker_err(e: DockerError) -> ErrorTrace<DockerError> {
ErrorTrace::new(e)
}
#[must_use]
pub fn map_docker_client_err(e: foundation_deployment_docker::DockerError) -> ErrorTrace<DockerError> {
use foundation_deployment_docker::DockerError as De;
docker_err(match e {
De::Transport(m) | De::Unavailable(m) => DockerError::Connection(m),
De::JsonParse(m) => DockerError::InvalidConfig(m),
De::BuildFailed(m) => DockerError::ImageBuild(m),
De::Api { status, message } => {
DockerError::Connection(format!("docker API {status}: {message}"))
}
})
}