gatekpr_opencode/
error.rs1use thiserror::Error;
4
5pub type Result<T> = std::result::Result<T, OpenCodeError>;
7
8#[derive(Error, Debug)]
10pub enum OpenCodeError {
11 #[error(
13 "OpenCode CLI not found: {0}. Install with: curl -fsSL https://opencode.ai/install | bash"
14 )]
15 CliNotFound(String),
16
17 #[error("CLI execution failed: {0}")]
19 CliExecution(String),
20
21 #[error("CLI exited with code {code}: {stderr}")]
23 CliExitError { code: i32, stderr: String },
24
25 #[error("CLI operation timed out after {0} seconds")]
27 Timeout(u64),
28
29 #[error("Failed to parse CLI output: {0}")]
31 OutputParse(String),
32
33 #[error("JSON error: {0}")]
35 Json(#[from] serde_json::Error),
36
37 #[error("IO error: {0}")]
39 Io(#[from] std::io::Error),
40
41 #[error("Invalid configuration: {0}")]
43 InvalidConfig(String),
44
45 #[error("MCP server error: {0}")]
47 McpError(String),
48
49 #[error("OpenCode authentication required. Run: opencode auth login")]
51 AuthRequired,
52
53 #[error("No results found for: {0}")]
55 NoResults(String),
56
57 #[error("Rate limit exceeded. Try again later.")]
59 RateLimited,
60
61 #[error("Model not available: {0}. Check your subscription.")]
63 ModelUnavailable(String),
64
65 #[error("Failed to collect files: {0}")]
67 FileCollection(String),
68}
69
70impl OpenCodeError {
71 pub fn cli_error(message: impl Into<String>) -> Self {
73 Self::CliExecution(message.into())
74 }
75
76 pub fn exit_error(code: i32, stderr: impl Into<String>) -> Self {
78 Self::CliExitError {
79 code,
80 stderr: stderr.into(),
81 }
82 }
83
84 pub fn timeout(seconds: u64) -> Self {
86 Self::Timeout(seconds)
87 }
88
89 pub fn parse_error(message: impl Into<String>) -> Self {
91 Self::OutputParse(message.into())
92 }
93
94 pub fn is_retryable(&self) -> bool {
96 matches!(
97 self,
98 Self::Timeout(_) | Self::RateLimited | Self::CliExecution(_)
99 )
100 }
101
102 pub fn needs_auth(&self) -> bool {
104 matches!(self, Self::AuthRequired)
105 }
106
107 pub fn is_config_error(&self) -> bool {
109 matches!(
110 self,
111 Self::CliNotFound(_) | Self::InvalidConfig(_) | Self::ModelUnavailable(_)
112 )
113 }
114}