git_same/errors/
provider.rs1use thiserror::Error;
7
8#[derive(Error, Debug)]
10pub enum ProviderError {
11 #[error("Authentication failed: {0}")]
13 Authentication(String),
14
15 #[error("Network error: {0}")]
17 Network(String),
18
19 #[error("API error (HTTP {status}): {message}")]
21 Api {
22 status: u16,
24 message: String,
26 },
27
28 #[error("Rate limited. Resets at {reset_time}")]
30 RateLimited {
31 reset_time: String,
33 },
34
35 #[error("Failed to parse response: {0}")]
37 Parse(String),
38
39 #[error("Configuration error: {0}")]
41 Configuration(String),
42
43 #[error("Not implemented: {0}")]
45 NotImplemented(String),
46
47 #[error("Not found: {0}")]
49 NotFound(String),
50
51 #[error("Permission denied: {0}")]
53 PermissionDenied(String),
54}
55
56impl ProviderError {
57 pub fn is_retryable(&self) -> bool {
65 matches!(
66 self,
67 ProviderError::Network(_)
68 | ProviderError::RateLimited { .. }
69 | ProviderError::Api { status: 429, .. }
70 | ProviderError::Api {
71 status: 500..=599,
72 ..
73 }
74 )
75 }
76
77 pub fn suggested_action(&self) -> &'static str {
79 match self {
80 ProviderError::Authentication(_) => {
81 "Re-authenticate with your Git provider or verify your access token/credentials"
82 }
83 ProviderError::RateLimited { .. } => {
84 "Wait for the rate limit to reset, or use a different authentication token"
85 }
86 ProviderError::Network(_) => "Check your internet connection and try again",
87 ProviderError::Api { status: 403, .. } => {
88 "Check that your token has the required permissions for this operation"
89 }
90 ProviderError::Api { status: 404, .. } | ProviderError::NotFound(_) => {
91 "The resource may have been deleted or you may have lost access"
92 }
93 ProviderError::PermissionDenied(_) => {
94 "Check that your token has the required permissions for this operation"
95 }
96 ProviderError::Configuration(_) => "Check your gisa.config.toml configuration file",
97 ProviderError::NotImplemented(_) => {
98 "This feature is not yet available. Check for updates"
99 }
100 _ => "Please check the error message and try again",
101 }
102 }
103
104 pub fn from_status(status: u16, message: impl Into<String>) -> Self {
106 let message = message.into();
107 match status {
108 401 => ProviderError::Authentication(message),
109 403 => ProviderError::PermissionDenied(message),
110 404 => ProviderError::NotFound(message),
111 _ => ProviderError::Api { status, message },
112 }
113 }
114}
115
116#[cfg(test)]
117#[path = "provider_tests.rs"]
118mod tests;