1use thiserror::Error;
9
10#[derive(Error, Debug)]
12pub enum AptuError {
13 #[error("GitHub API error: {message}")]
15 GitHub {
16 message: String,
18 },
19
20 #[error("AI provider error: {message}")]
22 AI {
23 message: String,
25 status: Option<u16>,
27 },
28
29 #[error(
31 "Authentication required - run `aptu auth login` first, or set GITHUB_TOKEN environment variable"
32 )]
33 NotAuthenticated,
34
35 #[error("Rate limit exceeded on {provider}, retry after {retry_after}s")]
37 RateLimited {
38 provider: String,
40 retry_after: u64,
42 },
43
44 #[error("Configuration error: {message}")]
46 Config {
47 message: String,
49 },
50
51 #[error("Invalid JSON response from AI")]
53 InvalidAIResponse(#[source] serde_json::Error),
54
55 #[error("Network error: {0}")]
57 Network(#[from] reqwest::Error),
58
59 #[cfg(feature = "keyring")]
61 #[error("Keyring error: {0}")]
62 Keyring(#[from] keyring::Error),
63
64 #[error("Circuit breaker is open - AI provider is temporarily unavailable")]
66 CircuitOpen,
67}
68
69impl From<octocrab::Error> for AptuError {
70 fn from(err: octocrab::Error) -> Self {
71 AptuError::GitHub {
72 message: err.to_string(),
73 }
74 }
75}
76
77impl From<config::ConfigError> for AptuError {
78 fn from(err: config::ConfigError) -> Self {
79 AptuError::Config {
80 message: err.to_string(),
81 }
82 }
83}