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 #[error("Keyring error: {0}")]
61 Keyring(#[from] keyring::Error),
62
63 #[error("Circuit breaker is open - AI provider is temporarily unavailable")]
65 CircuitOpen,
66}
67
68impl From<octocrab::Error> for AptuError {
69 fn from(err: octocrab::Error) -> Self {
70 AptuError::GitHub {
71 message: err.to_string(),
72 }
73 }
74}
75
76impl From<config::ConfigError> for AptuError {
77 fn from(err: config::ConfigError) -> Self {
78 AptuError::Config {
79 message: err.to_string(),
80 }
81 }
82}