Skip to main content

agent_tui_common/common/
error_codes.rs

1//! Exit code definitions.
2
3pub const SESSION_NOT_FOUND: i32 = -32001;
4pub const NO_ACTIVE_SESSION: i32 = -32002;
5pub const SESSION_LIMIT: i32 = -32006;
6pub const LOCK_TIMEOUT: i32 = -32007;
7pub const SESSION_ALREADY_EXISTS: i32 = -32018;
8pub const INVALID_INPUT: i32 = -32019;
9
10pub const INVALID_KEY: i32 = -32005;
11pub const PTY_ERROR: i32 = -32008;
12
13pub const WAIT_TIMEOUT: i32 = -32013;
14
15pub const COMMAND_NOT_FOUND: i32 = -32014;
16pub const PERMISSION_DENIED: i32 = -32015;
17
18pub const DAEMON_ERROR: i32 = -32016;
19pub const PERSISTENCE_ERROR: i32 = -32017;
20
21pub const GENERIC_ERROR: i32 = -32000;
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24pub enum ErrorCategory {
25    NotFound,
26    InvalidInput,
27    Busy,
28    Internal,
29    External,
30    Timeout,
31}
32
33impl ErrorCategory {
34    pub fn as_str(&self) -> &'static str {
35        match self {
36            ErrorCategory::NotFound => "not_found",
37            ErrorCategory::InvalidInput => "invalid_input",
38            ErrorCategory::Busy => "busy",
39            ErrorCategory::Internal => "internal",
40            ErrorCategory::External => "external",
41            ErrorCategory::Timeout => "timeout",
42        }
43    }
44}
45
46impl std::str::FromStr for ErrorCategory {
47    type Err = ();
48
49    fn from_str(s: &str) -> Result<Self, Self::Err> {
50        match s {
51            "not_found" => Ok(ErrorCategory::NotFound),
52            "invalid_input" => Ok(ErrorCategory::InvalidInput),
53            "busy" => Ok(ErrorCategory::Busy),
54            "internal" => Ok(ErrorCategory::Internal),
55            "external" => Ok(ErrorCategory::External),
56            "timeout" => Ok(ErrorCategory::Timeout),
57            _ => Err(()),
58        }
59    }
60}
61
62impl std::fmt::Display for ErrorCategory {
63    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64        write!(f, "{}", self.as_str())
65    }
66}
67
68pub fn is_retryable(code: i32) -> bool {
69    matches!(code, LOCK_TIMEOUT | GENERIC_ERROR)
70}
71
72pub fn category_for_code(code: i32) -> ErrorCategory {
73    match code {
74        SESSION_NOT_FOUND | NO_ACTIVE_SESSION => ErrorCategory::NotFound,
75        INVALID_KEY | SESSION_ALREADY_EXISTS | INVALID_INPUT => ErrorCategory::InvalidInput,
76        SESSION_LIMIT | LOCK_TIMEOUT => ErrorCategory::Busy,
77        PTY_ERROR | COMMAND_NOT_FOUND | PERMISSION_DENIED | DAEMON_ERROR | PERSISTENCE_ERROR => {
78            ErrorCategory::External
79        }
80        WAIT_TIMEOUT => ErrorCategory::Timeout,
81        _ => ErrorCategory::Internal,
82    }
83}
84
85#[cfg(test)]
86#[path = "error_codes_tests.rs"]
87mod tests;