Skip to main content

factorio_rcon/
error.rs

1use std::io;
2use thiserror::Error;
3
4/// RCON client errors
5#[derive(Debug, Error)]
6pub enum RconError {
7    /// Initial TCP connection failed
8    #[error("Failed to connect to RCON server: {0}")]
9    ConnectionFailed(#[source] io::Error),
10
11    /// Authentication failed (wrong password)
12    #[error("Authentication failed: incorrect password")]
13    AuthFailed,
14
15    /// Operation timed out
16    #[error("Operation timed out after {0}ms")]
17    Timeout(u64),
18
19    /// Connection lost during operation
20    #[error("Connection lost: {0}")]
21    ConnectionLost(#[source] io::Error),
22
23    /// Invalid server response
24    #[error("Protocol error: {0}")]
25    ProtocolError(String),
26
27    /// Malformed packet structure
28    #[error("Invalid packet: {0}")]
29    InvalidPacket(String),
30
31    /// Generic IO error
32    #[error("IO error: {0}")]
33    Io(#[from] io::Error),
34}
35
36/// Result type alias for RCON operations
37pub type Result<T> = std::result::Result<T, RconError>;
38
39#[cfg(test)]
40mod tests {
41    use super::*;
42    use std::io;
43
44    #[test]
45    fn test_error_display() {
46        let err = RconError::AuthFailed;
47        assert_eq!(err.to_string(), "Authentication failed: incorrect password");
48
49        let err = RconError::Timeout(5000);
50        assert_eq!(err.to_string(), "Operation timed out after 5000ms");
51
52        let err = RconError::ProtocolError("unexpected response".into());
53        assert_eq!(err.to_string(), "Protocol error: unexpected response");
54    }
55
56    #[test]
57    fn test_from_io_error() {
58        let io_err = io::Error::new(io::ErrorKind::ConnectionRefused, "refused");
59        let rcon_err: RconError = io_err.into();
60        assert!(matches!(rcon_err, RconError::Io(_)));
61    }
62}