claude_code_toolkit/
error.rs

1//! Error types and handling for the Claude Code Toolkit.
2//!
3//! This module defines comprehensive error types using the [`thiserror`] crate
4//! for consistent error handling throughout the toolkit. All errors implement
5//! standard traits and provide detailed context for debugging and user feedback.
6
7use thiserror::Error;
8
9/// Main error type for the Claude Code Toolkit.
10///
11/// This enum covers all possible error conditions that can occur during
12/// toolkit operations, from file I/O and network errors to configuration
13/// and validation failures. Each variant provides specific context about
14/// the error condition.
15///
16/// # Examples
17///
18/// ```rust
19/// use claude_code_toolkit::{ClaudeCodeError, Result};
20///
21/// fn validate_repo_format(repo: &str) -> Result<()> {
22///     if !repo.contains('/') {
23///         return Err(ClaudeCodeError::InvalidRepoFormat {
24///             repo: repo.to_string(),
25///         });
26///     }
27///     Ok(())
28/// }
29/// ```
30#[derive(Error, Debug)]
31pub enum ClaudeCodeError {
32  /// File system I/O operation failed
33  #[error("IO error: {0}")] 
34  Io(#[from] std::io::Error),
35
36  /// JSON serialization or deserialization failed
37  #[error("JSON error: {0}")] 
38  Json(#[from] serde_json::Error),
39
40  /// YAML parsing or generation failed
41  #[error("YAML error: {0}")] 
42  Yaml(#[from] serde_yaml::Error),
43
44  /// External process execution failed
45  #[error("Process execution error: {0}")] 
46  Process(String),
47
48  /// HTTP request or response error
49  #[error("HTTP error: {0}")] 
50  Http(#[from] reqwest::Error),
51
52  /// Configuration file or settings validation failed
53  #[error("Configuration error: {0}")] 
54  InvalidConfig(String),
55
56  /// External provider (GitHub, etc.) integration error
57  #[error("Provider error: {0}")] 
58  Provider(String),
59
60  /// Input validation or constraint violation
61  #[error("Validation error: {0}")] 
62  Validation(String),
63
64  /// Initial setup or configuration wizard error
65  #[error("Setup error: {0}")] 
66  Setup(String),
67
68  /// Claude Code credentials file not found
69  #[error("Credentials not found at {path}")] 
70  CredentialsNotFound {
71    /// File system path where credentials were expected
72    path: String,
73  },
74
75  /// Credentials file format is invalid or corrupted
76  #[error("Invalid credentials format: {0}")] 
77  InvalidCredentials(String),
78
79  /// Date/time parsing failed
80  #[error("Time parsing error: {0}")] 
81  Time(#[from] chrono::ParseError),
82
83  /// Desktop notification system error
84  #[error("Notification error: {0}")] 
85  Notification(String),
86
87  /// Systemd service management error (Linux only)
88  #[error("Systemd error: {0}")] 
89  Systemd(String),
90
91  /// Daemon service is not currently running
92  #[error("Daemon not running")]
93  DaemonNotRunning,
94
95  /// Daemon service is already running
96  #[error("Daemon already running")]
97  DaemonAlreadyRunning,
98
99  /// Access denied to specified resource
100  #[error("Access denied to {target_type}: {name}")] 
101  AccessDenied {
102    /// Type of target (organization, repository, etc.)
103    target_type: String,
104    /// Name of the target that access was denied to
105    name: String,
106  },
107
108  /// Specified target (org, repo) not found
109  #[error("Target not found: {target_type} '{name}'")] 
110  TargetNotFound {
111    /// Type of target that was not found
112    target_type: String,
113    /// Name of the target that was not found
114    name: String,
115  },
116
117  /// Repository name format is invalid (should be "owner/repo")
118  #[error("Invalid repository format: {repo} (expected 'owner/repository')")] 
119  InvalidRepoFormat {
120    /// The invalid repository string provided
121    repo: String,
122  },
123
124  /// Catch-all for other error conditions
125  #[error("Generic error: {0}")] 
126  Generic(String),
127}
128
129/// Convenient type alias for Results using [`ClaudeCodeError`].
130///
131/// This type alias simplifies function signatures throughout the codebase
132/// by providing a default error type for all operations.
133///
134/// # Examples
135///
136/// ```rust
137/// use claude_code_toolkit::Result;
138///
139/// fn may_fail() -> Result<String> {
140///     Ok("success".to_string())
141/// }
142/// ```
143pub type Result<T> = std::result::Result<T, ClaudeCodeError>;
144
145impl From<String> for ClaudeCodeError {
146  fn from(s: String) -> Self {
147    ClaudeCodeError::Generic(s)
148  }
149}
150
151impl From<&str> for ClaudeCodeError {
152  fn from(s: &str) -> Self {
153    ClaudeCodeError::Generic(s.to_string())
154  }
155}