proc_cli/
error.rs

1//! Error types for proc CLI
2//!
3//! Provides structured error handling with helpful suggestions for users.
4
5use thiserror::Error;
6
7/// Main error type for proc operations
8#[derive(Error, Debug)]
9pub enum ProcError {
10    #[error("No process found matching '{0}'\n  Try: proc find --all")]
11    ProcessNotFound(String),
12
13    #[error("No process listening on port {0}\n  Try: proc ports")]
14    PortNotFound(u16),
15
16    #[error("Permission denied for PID {0}\n  Try: sudo proc <command>")]
17    PermissionDenied(u32),
18
19    #[error("Invalid input: {0}")]
20    InvalidInput(String),
21
22    #[error("System error: {0}")]
23    SystemError(String),
24
25    #[error("Operation timed out: {0}")]
26    Timeout(String),
27
28    #[error("Failed to parse: {0}")]
29    ParseError(String),
30
31    #[error("Not supported on this platform: {0}")]
32    NotSupported(String),
33
34    #[error("Process {0} is no longer running")]
35    ProcessGone(u32),
36
37    #[error("Signal failed: {0}")]
38    SignalError(String),
39}
40
41impl From<std::io::Error> for ProcError {
42    fn from(err: std::io::Error) -> Self {
43        match err.kind() {
44            std::io::ErrorKind::PermissionDenied => ProcError::PermissionDenied(0),
45            std::io::ErrorKind::NotFound => ProcError::ProcessNotFound("unknown".to_string()),
46            _ => ProcError::SystemError(err.to_string()),
47        }
48    }
49}
50
51impl From<serde_json::Error> for ProcError {
52    fn from(err: serde_json::Error) -> Self {
53        ProcError::ParseError(err.to_string())
54    }
55}
56
57impl From<regex::Error> for ProcError {
58    fn from(err: regex::Error) -> Self {
59        ProcError::InvalidInput(format!("Invalid pattern: {}", err))
60    }
61}
62
63impl From<dialoguer::Error> for ProcError {
64    fn from(err: dialoguer::Error) -> Self {
65        ProcError::SystemError(format!("Dialog error: {}", err))
66    }
67}
68
69/// Result type alias for proc operations
70pub type Result<T> = std::result::Result<T, ProcError>;
71
72/// Exit codes for CLI
73#[derive(Debug, Clone, Copy)]
74pub enum ExitCode {
75    Success = 0,
76    GeneralError = 1,
77    NotFound = 2,
78    PermissionDenied = 3,
79    InvalidInput = 4,
80}
81
82impl From<&ProcError> for ExitCode {
83    fn from(err: &ProcError) -> Self {
84        match err {
85            ProcError::ProcessNotFound(_) | ProcError::PortNotFound(_) => ExitCode::NotFound,
86            ProcError::PermissionDenied(_) => ExitCode::PermissionDenied,
87            ProcError::InvalidInput(_) => ExitCode::InvalidInput,
88            _ => ExitCode::GeneralError,
89        }
90    }
91}