Skip to main content

dot_agent_core/
error.rs

1use std::path::PathBuf;
2use thiserror::Error;
3
4#[derive(Debug, Error)]
5pub enum DotAgentError {
6    #[error("Profile not found: {name}")]
7    ProfileNotFound { name: String },
8
9    #[error("Target directory does not exist: {path}")]
10    TargetNotFound { path: PathBuf },
11
12    #[error("Profile already exists: {name}")]
13    ProfileAlreadyExists { name: String },
14
15    #[error("Invalid profile name: '{name}' - must contain only alphanumeric, hyphen, underscore")]
16    InvalidProfileName { name: String },
17
18    #[error("Conflict detected - file exists with different content: {path}")]
19    Conflict { path: PathBuf },
20
21    #[error("Local modifications detected: {paths:?}")]
22    LocalModifications { paths: Vec<PathBuf> },
23
24    #[error("IO error: {0}")]
25    Io(#[from] std::io::Error),
26
27    #[error("TOML serialization error: {0}")]
28    TomlSer(#[from] toml::ser::Error),
29
30    #[error("TOML deserialization error: {0}")]
31    TomlDe(#[from] toml::de::Error),
32
33    #[error("Home directory not found")]
34    HomeNotFound,
35
36    #[error("GUI error: {0}")]
37    Gui(String),
38
39    #[error("Git error: {0}")]
40    Git(String),
41
42    #[error("Rule not found: {name}")]
43    RuleNotFound { name: String },
44
45    #[error("Rule already exists: {name}")]
46    RuleAlreadyExists { name: String },
47
48    #[error("Invalid rule name: '{name}' - must be alphanumeric, hyphen, underscore, 1-64 chars")]
49    InvalidRuleName { name: String },
50
51    #[error("Claude CLI not found. Install with: brew install claude")]
52    ClaudeNotFound,
53
54    #[error("Claude CLI execution failed: {message}")]
55    ClaudeExecutionFailed { message: String },
56
57    #[error("Glob pattern error: {0}")]
58    GlobPattern(#[from] glob::PatternError),
59
60    #[error("Glob error: {0}")]
61    Glob(#[from] glob::GlobError),
62
63    #[error("Snapshot not found: {id}")]
64    SnapshotNotFound { id: String },
65
66    #[error("Config parse error in {path}: {message}")]
67    ConfigParse { path: PathBuf, message: String },
68
69    #[error("Config key not found: {key}")]
70    ConfigKeyNotFound { key: String },
71
72    #[error("Config parse error: {message}")]
73    ConfigParseSimple { message: String },
74
75    #[error("GitHub CLI (gh) not found. Install with: brew install gh")]
76    GitHubCliNotFound,
77
78    #[error("GitHub API error: {message}")]
79    GitHubApiError { message: String },
80
81    #[error("Hub already exists: {name}")]
82    HubAlreadyExists { name: String },
83
84    #[error("Hub not found: {name}")]
85    HubNotFound { name: String },
86
87    #[error("Cannot remove default hub")]
88    CannotRemoveDefaultHub,
89
90    #[error("Channel already exists: {name}")]
91    ChannelAlreadyExists { name: String },
92
93    #[error("Channel not found: {name}")]
94    ChannelNotFound { name: String },
95
96    #[error("Cannot remove built-in channel: {name}")]
97    CannotRemoveBuiltinChannel { name: String },
98
99    #[error("JSON parse error: {message}")]
100    JsonParseError { message: String },
101
102    #[error("JSON error: {0}")]
103    Json(#[from] serde_json::Error),
104
105    #[error("TOML parse error in {path}: {message}")]
106    TomlError { path: PathBuf, message: String },
107
108    #[error("Category not found: {name}")]
109    CategoryNotFound { name: String },
110
111    #[error("Fusion conflict: {path} exists in multiple profiles")]
112    FusionConflict { path: PathBuf },
113
114    #[error("LLM classification failed: {message}")]
115    LlmClassificationFailed { message: String },
116
117    #[error("Internal error: {0}")]
118    Internal(String),
119
120    #[error("Not found: {0}")]
121    NotFound(String),
122
123    #[error("Operation not found: {id}")]
124    OperationNotFound { id: String },
125
126    #[error("Checkpoint not found: {id}")]
127    CheckpointNotFound { id: String },
128
129    #[error("Operation aborted by user")]
130    Aborted,
131}
132
133pub type Result<T> = std::result::Result<T, DotAgentError>;
134
135impl DotAgentError {
136    pub fn exit_code(&self) -> i32 {
137        match self {
138            Self::ProfileNotFound { .. } => 2,
139            Self::TargetNotFound { .. } => 3,
140            Self::LocalModifications { .. } => 4,
141            Self::InvalidProfileName { .. } => 5,
142            Self::Conflict { .. } => 6,
143            Self::RuleNotFound { .. } => 7,
144            Self::RuleAlreadyExists { .. } => 8,
145            Self::InvalidRuleName { .. } => 9,
146            Self::ClaudeNotFound => 10,
147            Self::ClaudeExecutionFailed { .. } => 11,
148            Self::SnapshotNotFound { .. } => 12,
149            Self::ConfigParse { .. } => 13,
150            Self::ConfigKeyNotFound { .. } => 14,
151            Self::ConfigParseSimple { .. } => 15,
152            Self::GitHubCliNotFound => 16,
153            Self::GitHubApiError { .. } => 17,
154            Self::HubAlreadyExists { .. } => 18,
155            Self::HubNotFound { .. } => 19,
156            Self::CannotRemoveDefaultHub => 20,
157            Self::ChannelAlreadyExists { .. } => 21,
158            Self::ChannelNotFound { .. } => 22,
159            Self::CannotRemoveBuiltinChannel { .. } => 23,
160            Self::JsonParseError { .. } => 24,
161            Self::CategoryNotFound { .. } => 25,
162            Self::FusionConflict { .. } => 26,
163            Self::LlmClassificationFailed { .. } => 27,
164            Self::Internal(_) => 28,
165            Self::NotFound(_) => 29,
166            Self::OperationNotFound { .. } => 30,
167            Self::CheckpointNotFound { .. } => 31,
168            Self::Aborted => 32,
169            _ => 1,
170        }
171    }
172}