1use std::fmt;
2
3#[derive(Debug)]
4#[non_exhaustive]
5pub enum GitHubError {
6 NetworkError(String),
7 AuthenticationError(String),
8 NotFoundError(String),
9 RateLimitError(String),
10 AccessBlockedError(String),
11 DmcaBlockedError(String),
12 InvalidInput(String),
13 ApiError { status: u16, message: String },
14 ParseError(String),
15 ConfigError(String),
16}
17
18impl fmt::Display for GitHubError {
19 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20 match self {
21 GitHubError::NetworkError(msg) => {
22 write!(
23 f,
24 "Network error: {}. Please check your internet connection",
25 msg
26 )
27 }
28 GitHubError::AuthenticationError(msg) => {
29 write!(
30 f,
31 "Authentication error: {}. Please check your GitHub token",
32 msg
33 )
34 }
35 GitHubError::NotFoundError(msg) => {
36 write!(
37 f,
38 "Repository not found: {}. Please verify the owner and repository name",
39 msg
40 )
41 }
42 GitHubError::RateLimitError(msg) => {
43 write!(
44 f,
45 "Rate limit exceeded: {}. Please wait or use a GitHub token for higher limits",
46 msg
47 )
48 }
49 GitHubError::AccessBlockedError(msg) => {
50 write!(
51 f,
52 "Repository access blocked: {}. This repository is inaccessible due to policy violations",
53 msg
54 )
55 }
56 GitHubError::DmcaBlockedError(msg) => {
57 write!(
58 f,
59 "Repository blocked for legal reasons (DMCA): {}. This repository is permanently inaccessible",
60 msg
61 )
62 }
63 GitHubError::InvalidInput(msg) => {
64 write!(f, "Invalid input: {}. Use format 'owner/repo'", msg)
65 }
66 GitHubError::ApiError { status, message } => {
67 write!(f, "GitHub API error {}: {}", status, message)
68 }
69 GitHubError::ParseError(msg) => {
70 write!(f, "Failed to parse response: {}", msg)
71 }
72 GitHubError::ConfigError(msg) => {
73 write!(f, "Configuration error: {}", msg)
74 }
75 }
76 }
77}
78
79impl std::error::Error for GitHubError {}
80
81impl From<reqwest::Error> for GitHubError {
82 fn from(error: reqwest::Error) -> Self {
83 if error.is_timeout() {
84 GitHubError::NetworkError("Request timeout".to_string())
85 } else if error.is_connect() {
86 GitHubError::NetworkError("Connection failed".to_string())
87 } else {
88 GitHubError::NetworkError(error.to_string())
89 }
90 }
91}
92
93impl From<serde_json::Error> for GitHubError {
94 fn from(error: serde_json::Error) -> Self {
95 GitHubError::ParseError(error.to_string())
96 }
97}
98
99pub type Result<T> = std::result::Result<T, GitHubError>;