unistore_process/
error.rs

1//! 进程错误类型
2//!
3//! 职责:定义进程操作的所有错误类型
4
5use std::fmt;
6
7/// 进程错误
8#[derive(Debug)]
9pub enum ProcessError {
10    /// 进程启动失败
11    SpawnFailed(String),
12
13    /// 进程未运行
14    NotRunning,
15
16    /// 进程已终止
17    AlreadyTerminated,
18
19    /// 等待超时
20    WaitTimeout,
21
22    /// IO 错误
23    IoError(String),
24
25    /// 命令不存在
26    CommandNotFound(String),
27
28    /// 权限错误
29    PermissionDenied(String),
30
31    /// 工作目录无效
32    InvalidWorkDir(String),
33
34    /// 信号发送失败
35    SignalFailed(String),
36
37    /// UTF-8 解码失败
38    Utf8Error(String),
39
40    /// 内部错误
41    Internal(String),
42}
43
44impl fmt::Display for ProcessError {
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46        match self {
47            Self::SpawnFailed(msg) => write!(f, "进程启动失败: {}", msg),
48            Self::NotRunning => write!(f, "进程未运行"),
49            Self::AlreadyTerminated => write!(f, "进程已终止"),
50            Self::WaitTimeout => write!(f, "等待超时"),
51            Self::IoError(msg) => write!(f, "IO 错误: {}", msg),
52            Self::CommandNotFound(cmd) => write!(f, "命令不存在: {}", cmd),
53            Self::PermissionDenied(msg) => write!(f, "权限不足: {}", msg),
54            Self::InvalidWorkDir(dir) => write!(f, "无效的工作目录: {}", dir),
55            Self::SignalFailed(msg) => write!(f, "信号发送失败: {}", msg),
56            Self::Utf8Error(msg) => write!(f, "UTF-8 解码失败: {}", msg),
57            Self::Internal(msg) => write!(f, "内部错误: {}", msg),
58        }
59    }
60}
61
62impl std::error::Error for ProcessError {}
63
64impl From<std::io::Error> for ProcessError {
65    fn from(err: std::io::Error) -> Self {
66        use std::io::ErrorKind;
67        match err.kind() {
68            ErrorKind::NotFound => Self::CommandNotFound(err.to_string()),
69            ErrorKind::PermissionDenied => Self::PermissionDenied(err.to_string()),
70            ErrorKind::TimedOut => Self::WaitTimeout,
71            _ => Self::IoError(err.to_string()),
72        }
73    }
74}
75
76impl From<std::string::FromUtf8Error> for ProcessError {
77    fn from(err: std::string::FromUtf8Error) -> Self {
78        Self::Utf8Error(err.to_string())
79    }
80}
81
82#[cfg(test)]
83mod tests {
84    use super::*;
85
86    #[test]
87    fn test_error_display() {
88        let err = ProcessError::CommandNotFound("git".into());
89        assert!(err.to_string().contains("git"));
90
91        let err = ProcessError::WaitTimeout;
92        assert!(err.to_string().contains("超时"));
93    }
94
95    #[test]
96    fn test_io_error_conversion() {
97        let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "not found");
98        let process_err: ProcessError = io_err.into();
99        assert!(matches!(process_err, ProcessError::CommandNotFound(_)));
100    }
101}