1use thiserror::Error;
6
7#[derive(Error, Debug)]
9pub enum ProcError {
10 #[error("No process found matching '{0}'\n Try: proc list to list all processes")]
12 ProcessNotFound(String),
13
14 #[error("No process listening on port {0}\n Try: proc ports")]
16 PortNotFound(u16),
17
18 #[error("Permission denied for PID {0}\n Try: sudo proc <command>")]
20 PermissionDenied(u32),
21
22 #[error("Invalid input: {0}")]
24 InvalidInput(String),
25
26 #[error("System error: {0}")]
28 SystemError(String),
29
30 #[error("Operation timed out: {0}")]
32 Timeout(String),
33
34 #[error("Failed to parse: {0}")]
36 ParseError(String),
37
38 #[error("Not supported on this platform: {0}")]
40 NotSupported(String),
41
42 #[error("Process {0} is no longer running")]
44 ProcessGone(u32),
45
46 #[error("Signal failed: {0}")]
48 SignalError(String),
49
50 #[error("{message}")]
54 Reported {
55 message: String,
57 exit_code: ExitCode,
59 },
60}
61
62impl ProcError {
63 pub fn reported(exit_code: ExitCode, message: impl Into<String>) -> Self {
65 ProcError::Reported {
66 message: message.into(),
67 exit_code,
68 }
69 }
70}
71
72impl From<std::io::Error> for ProcError {
73 fn from(err: std::io::Error) -> Self {
74 match err.kind() {
75 std::io::ErrorKind::PermissionDenied => ProcError::PermissionDenied(0),
76 std::io::ErrorKind::NotFound => ProcError::ProcessNotFound("unknown".to_string()),
77 _ => ProcError::SystemError(err.to_string()),
78 }
79 }
80}
81
82impl From<serde_json::Error> for ProcError {
83 fn from(err: serde_json::Error) -> Self {
84 ProcError::ParseError(err.to_string())
85 }
86}
87
88impl From<regex::Error> for ProcError {
89 fn from(err: regex::Error) -> Self {
90 ProcError::InvalidInput(format!("Invalid pattern: {}", err))
91 }
92}
93
94impl From<dialoguer::Error> for ProcError {
95 fn from(err: dialoguer::Error) -> Self {
96 ProcError::SystemError(format!("Dialog error: {}", err))
97 }
98}
99
100pub type Result<T> = std::result::Result<T, ProcError>;
102
103#[derive(Debug, Clone, Copy, PartialEq, Eq)]
105pub enum ExitCode {
106 Success = 0,
108 GeneralError = 1,
110 NotFound = 2,
112 PermissionDenied = 3,
114 InvalidInput = 4,
116}
117
118impl From<&ProcError> for ExitCode {
119 fn from(err: &ProcError) -> Self {
120 match err {
121 ProcError::ProcessNotFound(_) | ProcError::PortNotFound(_) => ExitCode::NotFound,
122 ProcError::PermissionDenied(_) => ExitCode::PermissionDenied,
123 ProcError::InvalidInput(_) => ExitCode::InvalidInput,
124 ProcError::Reported { exit_code, .. } => *exit_code,
125 _ => ExitCode::GeneralError,
126 }
127 }
128}