proc_connector/error.rs
1//! Error types for proc-connector operations.
2
3use std::fmt;
4
5/// Errors that can occur during proc connector operations.
6///
7/// # Example: matching on errors
8///
9/// ```
10/// use proc_connector::Error;
11///
12/// fn handle_error(e: Error) -> String {
13/// match &e {
14/// Error::Os(e) => format!("os error: {e}"),
15/// Error::Truncated => "truncated message".into(),
16/// Error::BufferTooSmall { needed } => {
17/// format!("need {needed} bytes")
18/// }
19/// Error::Interrupted => "interrupted, retry".into(),
20/// Error::ConnectionClosed => "connection closed".into(),
21/// Error::Overrun => "events dropped".into(),
22/// Error::WouldBlock => "would block".into(),
23/// Error::UnexpectedConnector => "unexpected connector".into(),
24/// }
25/// }
26///
27/// assert_eq!(handle_error(Error::Truncated), "truncated message");
28/// assert_eq!(
29/// handle_error(Error::BufferTooSmall { needed: 4096 }),
30/// "need 4096 bytes"
31/// );
32/// ```
33///
34/// # Example: using the `From<std::io::Error>` impl
35///
36/// ```
37/// use proc_connector::Error;
38///
39/// fn returns_error() -> Result<(), Error> {
40/// // std::io::Error is automatically converted via From
41/// let _file = std::fs::File::open("/nonexistent")?;
42/// Ok(())
43/// }
44///
45/// let err = returns_error().unwrap_err();
46/// assert!(matches!(err, Error::Os(_)));
47/// ```
48#[derive(Debug)]
49pub enum Error {
50 /// System call failed (socket/bind/sendmsg/recvmsg).
51 ///
52 /// Wraps `std::io::Error` for maximum compatibility.
53 Os(std::io::Error),
54
55 /// Received message is shorter than the minimum protocol header size.
56 Truncated,
57
58 /// Provided receive buffer is too small.
59 BufferTooSmall {
60 /// Minimum buffer size required in bytes.
61 needed: usize,
62 },
63
64 /// Receive was interrupted by a signal; the operation should be retried.
65 Interrupted,
66
67 /// The netlink connection was closed (recv returned 0).
68 ConnectionClosed,
69
70 /// Kernel reports message overrun; some events may have been dropped.
71 ///
72 /// The caller should increase buffer size or consume events faster.
73 Overrun,
74
75 /// Non-blocking recv found no data available (EAGAIN / EWOULDBLOCK).
76 ///
77 /// Only returned when the socket is in non-blocking mode. Callers
78 /// should wait for fd readiness (e.g. via poll/AsyncFd) and retry.
79 WouldBlock,
80
81 /// 收到的消息不是proc connector事件(cn_msg idx != CN_IDX_PROC)。
82 UnexpectedConnector,
83}
84
85impl fmt::Display for Error {
86 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87 match self {
88 Error::Os(e) => write!(f, "system call error: {e}"),
89 Error::Truncated => write!(f, "truncated message"),
90 Error::BufferTooSmall { needed } => {
91 write!(f, "buffer too small, need at least {needed} bytes")
92 }
93 Error::Interrupted => write!(f, "interrupted by signal"),
94 Error::ConnectionClosed => write!(f, "connection closed"),
95 Error::Overrun => write!(f, "message overrun, events may have been dropped"),
96 Error::WouldBlock => write!(f, "operation would block"),
97 Error::UnexpectedConnector => {
98 write!(f, "unexpected connector index (expected CN_IDX_PROC)")
99 }
100 }
101 }
102}
103
104impl std::error::Error for Error {
105 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
106 match self {
107 Error::Os(e) => Some(e),
108 _ => None,
109 }
110 }
111}
112
113impl From<std::io::Error> for Error {
114 fn from(e: std::io::Error) -> Self {
115 Error::Os(e)
116 }
117}
118
119/// Convenience alias for `Result<T, Error>`.
120pub type Result<T> = std::result::Result<T, Error>;