docker_image_pusher/
error.rs

1//! Error handling for the docker image pusher
2//! Includes standardized error handlers to eliminate duplication
3
4pub mod handlers;
5
6use std::fmt;
7
8#[derive(Debug)]
9pub enum PusherError {
10    Config(String),
11    Authentication(String),
12    Network(String),
13    Upload(String),
14    Io(String),
15    Parse(String),
16    Registry(String),
17    ImageParsing(String),
18    Validation(String),
19    Timeout(String),
20}
21
22impl Clone for PusherError {
23    fn clone(&self) -> Self {
24        match self {
25            PusherError::Config(msg) => PusherError::Config(msg.clone()),
26            PusherError::Authentication(msg) => PusherError::Authentication(msg.clone()),
27            PusherError::Network(msg) => PusherError::Network(msg.clone()),
28            PusherError::Upload(msg) => PusherError::Upload(msg.clone()),
29            PusherError::Io(msg) => PusherError::Io(msg.clone()),
30            PusherError::Parse(msg) => PusherError::Parse(msg.clone()),
31            PusherError::Registry(msg) => PusherError::Registry(msg.clone()),
32            PusherError::ImageParsing(msg) => PusherError::ImageParsing(msg.clone()),
33            PusherError::Validation(msg) => PusherError::Validation(msg.clone()),
34            PusherError::Timeout(msg) => PusherError::Timeout(msg.clone()),
35        }
36    }
37}
38
39impl fmt::Display for PusherError {
40    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41        match self {
42            PusherError::Config(msg) => write!(f, "Configuration error: {}", msg),
43            PusherError::Authentication(msg) => write!(f, "Authentication failed: {}", msg),
44            PusherError::Network(msg) => write!(f, "Network error: {}", msg),
45            PusherError::Upload(msg) => write!(f, "Upload failed: {}", msg),
46            PusherError::Io(msg) => write!(f, "I/O error: {}", msg),
47            PusherError::Parse(msg) => write!(f, "Parse error: {}", msg),
48            PusherError::Registry(msg) => write!(f, "Registry error: {}", msg),
49            PusherError::ImageParsing(msg) => write!(f, "Image parsing failed: {}", msg),
50            PusherError::Validation(msg) => write!(f, "Validation error: {}", msg),
51            PusherError::Timeout(msg) => write!(f, "Operation timed out: {}", msg),
52        }
53    }
54}
55
56impl std::error::Error for PusherError {}
57
58// Enhanced From implementations with context
59impl From<std::io::Error> for PusherError {
60    fn from(err: std::io::Error) -> Self {
61        match err.kind() {
62            std::io::ErrorKind::NotFound => PusherError::Io(format!("File not found: {}", err)),
63            std::io::ErrorKind::PermissionDenied => PusherError::Io(format!("Permission denied: {}", err)),
64            std::io::ErrorKind::TimedOut => PusherError::Timeout(format!("I/O operation timed out: {}", err)),
65            _ => PusherError::Io(err.to_string()),
66        }
67    }
68}
69
70impl From<reqwest::Error> for PusherError {
71    fn from(err: reqwest::Error) -> Self {
72        if err.is_timeout() {
73            PusherError::Timeout(format!("Network request timed out: {}", err))
74        } else if err.is_connect() {
75            PusherError::Network(format!("Connection failed: {}", err))
76        } else if err.is_decode() {
77            PusherError::Parse(format!("Response decode error: {}", err))
78        } else {
79            PusherError::Network(err.to_string())
80        }
81    }
82}
83
84impl From<serde_json::Error> for PusherError {
85    fn from(err: serde_json::Error) -> Self {
86        PusherError::Parse(format!("JSON parsing failed: {}", err))
87    }
88}
89
90impl From<url::ParseError> for PusherError {
91    fn from(err: url::ParseError) -> Self {
92        PusherError::Config(format!("Invalid URL format: {}", err))
93    }
94}
95
96pub type Result<T> = std::result::Result<T, PusherError>;
97
98// Utility function for creating contextual errors
99pub fn context_error<T>(result: std::result::Result<T, PusherError>, context: &str) -> Result<T> {
100    result.map_err(|e| match e {
101        PusherError::Config(msg) => PusherError::Config(format!("{}: {}", context, msg)),
102        PusherError::Authentication(msg) => PusherError::Authentication(format!("{}: {}", context, msg)),
103        PusherError::Network(msg) => PusherError::Network(format!("{}: {}", context, msg)),
104        PusherError::Upload(msg) => PusherError::Upload(format!("{}: {}", context, msg)),
105        PusherError::Io(msg) => PusherError::Io(format!("{}: {}", context, msg)),
106        PusherError::Parse(msg) => PusherError::Parse(format!("{}: {}", context, msg)),
107        PusherError::Registry(msg) => PusherError::Registry(format!("{}: {}", context, msg)),
108        PusherError::ImageParsing(msg) => PusherError::ImageParsing(format!("{}: {}", context, msg)),
109        PusherError::Validation(msg) => PusherError::Validation(format!("{}: {}", context, msg)),
110        PusherError::Timeout(msg) => PusherError::Timeout(format!("{}: {}", context, msg)),
111    })
112}