Skip to main content

opencode_cloud_core/docker/
error.rs

1//! Docker-specific error types
2//!
3//! This module defines errors that can occur during Docker operations,
4//! providing clear, actionable messages for common issues.
5
6use thiserror::Error;
7
8/// Errors that can occur during Docker operations
9#[derive(Error, Debug)]
10pub enum DockerError {
11    /// Failed to connect to the Docker daemon
12    #[error("Docker connection failed: {0}")]
13    Connection(String),
14
15    /// Docker daemon is not running
16    #[error("Docker daemon not running. Start Docker Desktop or the Docker service.")]
17    NotRunning,
18
19    /// Permission denied accessing Docker socket
20    #[error(
21        "Permission denied accessing Docker socket. You may need to add your user to the 'docker' group."
22    )]
23    PermissionDenied,
24
25    /// Failed to build Docker image
26    #[error("Docker build failed: {0}")]
27    Build(String),
28
29    /// Failed to pull Docker image
30    #[error("Docker pull failed: {0}")]
31    Pull(String),
32
33    /// Container operation failed
34    #[error("Container operation failed: {0}")]
35    Container(String),
36
37    /// Volume operation failed
38    #[error("Volume operation failed: {0}")]
39    Volume(String),
40
41    /// Operation timed out
42    #[error("Docker operation timed out")]
43    Timeout,
44}
45
46impl From<bollard::errors::Error> for DockerError {
47    fn from(err: bollard::errors::Error) -> Self {
48        let msg = err.to_string();
49
50        // Detect common error patterns and provide better messages
51        if msg.contains("Cannot connect to the Docker daemon")
52            || msg.contains("connection refused")
53            || msg.contains("No such file or directory")
54        {
55            DockerError::NotRunning
56        } else if msg.contains("permission denied") || msg.contains("Permission denied") {
57            DockerError::PermissionDenied
58        } else {
59            DockerError::Connection(msg)
60        }
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    #[test]
69    fn docker_error_displays_correctly() {
70        let err = DockerError::NotRunning;
71        assert!(err.to_string().contains("Docker daemon not running"));
72
73        let err = DockerError::PermissionDenied;
74        assert!(err.to_string().contains("Permission denied"));
75
76        let err = DockerError::Build("layer failed".to_string());
77        assert!(err.to_string().contains("layer failed"));
78    }
79}