Skip to main content

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>;