Skip to main content

exeora_cli/
error.rs

1use serde::Serialize;
2use thiserror::Error;
3
4#[derive(Debug, Clone, Copy, Serialize, PartialEq, Eq)]
5pub enum ErrorCode {
6    #[serde(rename = "LOCAL_EXECUTOR_OFFLINE")]
7    LocalExecutorOffline,
8    #[serde(rename = "TOOL_TIMEOUT")]
9    ToolTimeout,
10    #[serde(rename = "CANCELLED")]
11    Cancelled,
12    #[serde(rename = "PATH_ESCAPE")]
13    PathEscape,
14    #[serde(rename = "PATH_NOT_FOUND")]
15    PathNotFound,
16    #[serde(rename = "TOOL_FAILED")]
17    ToolFailed,
18    #[serde(rename = "INVALID_ARGUMENTS")]
19    InvalidArguments,
20    #[serde(rename = "UNKNOWN_TOOL")]
21    UnknownTool,
22    #[serde(rename = "UNKNOWN_PROJECT")]
23    UnknownProject,
24    #[serde(rename = "UNKNOWN_WORKTREE")]
25    UnknownWorktree,
26    #[serde(rename = "WORKTREE_UNAVAILABLE")]
27    WorktreeUnavailable,
28    #[serde(rename = "NO_ACTIVE_PROJECT")]
29    NoActiveProject,
30    #[serde(rename = "FORBIDDEN")]
31    Forbidden,
32    #[serde(rename = "APPROVAL_DECLINED")]
33    ApprovalDeclined,
34    #[serde(rename = "APPROVAL_TIMEOUT")]
35    ApprovalTimeout,
36    #[serde(rename = "INTERNAL_ERROR")]
37    InternalError,
38}
39
40impl ErrorCode {
41    pub const fn as_str(self) -> &'static str {
42        match self {
43            Self::LocalExecutorOffline => "LOCAL_EXECUTOR_OFFLINE",
44            Self::ToolTimeout => "TOOL_TIMEOUT",
45            Self::Cancelled => "CANCELLED",
46            Self::PathEscape => "PATH_ESCAPE",
47            Self::PathNotFound => "PATH_NOT_FOUND",
48            Self::ToolFailed => "TOOL_FAILED",
49            Self::InvalidArguments => "INVALID_ARGUMENTS",
50            Self::UnknownTool => "UNKNOWN_TOOL",
51            Self::UnknownProject => "UNKNOWN_PROJECT",
52            Self::UnknownWorktree => "UNKNOWN_WORKTREE",
53            Self::WorktreeUnavailable => "WORKTREE_UNAVAILABLE",
54            Self::NoActiveProject => "NO_ACTIVE_PROJECT",
55            Self::Forbidden => "FORBIDDEN",
56            Self::ApprovalDeclined => "APPROVAL_DECLINED",
57            Self::ApprovalTimeout => "APPROVAL_TIMEOUT",
58            Self::InternalError => "INTERNAL_ERROR",
59        }
60    }
61}
62
63#[derive(Debug, Error)]
64#[error("{message}")]
65pub struct ExeoraError {
66    pub code: ErrorCode,
67    pub message: String,
68}
69
70impl ExeoraError {
71    pub fn new(code: ErrorCode, message: impl Into<String>) -> Self {
72        Self {
73            code,
74            message: message.into(),
75        }
76    }
77
78    pub fn tool(message: impl Into<String>) -> Self {
79        Self::new(ErrorCode::ToolFailed, message)
80    }
81}