Skip to main content

raknet_rust/
error.rs

1use thiserror::Error;
2
3#[derive(Debug, Error, Clone, PartialEq, Eq)]
4#[error("invalid config {config}.{field}: {message}")]
5pub struct ConfigValidationError {
6    pub config: &'static str,
7    pub field: &'static str,
8    pub message: String,
9}
10
11impl ConfigValidationError {
12    pub fn new(config: &'static str, field: &'static str, message: impl Into<String>) -> Self {
13        Self {
14            config,
15            field,
16            message: message.into(),
17        }
18    }
19}
20
21pub mod server {
22    use std::io;
23
24    use thiserror::Error;
25
26    use super::ConfigValidationError;
27
28    #[derive(Debug, Error, Clone, PartialEq, Eq)]
29    pub enum ServerError {
30        #[error("io error: {message}")]
31        Io { message: String },
32        #[error("invalid config: {details}")]
33        InvalidConfig { details: String },
34        #[error("listener is already started")]
35        AlreadyStarted,
36        #[error("listener is not started")]
37        NotStarted,
38        #[error("listener command channel closed")]
39        CommandChannelClosed,
40        #[error("listener accept channel closed")]
41        AcceptChannelClosed,
42        #[error("listener worker stopped unexpectedly")]
43        WorkerStopped,
44    }
45
46    impl From<io::Error> for ServerError {
47        fn from(value: io::Error) -> Self {
48            Self::Io {
49                message: value.to_string(),
50            }
51        }
52    }
53
54    impl From<ConfigValidationError> for ServerError {
55        fn from(value: ConfigValidationError) -> Self {
56            Self::InvalidConfig {
57                details: value.to_string(),
58            }
59        }
60    }
61
62    impl From<ServerError> for io::Error {
63        fn from(value: ServerError) -> Self {
64            let kind = match value {
65                ServerError::AlreadyStarted => io::ErrorKind::AlreadyExists,
66                ServerError::NotStarted => io::ErrorKind::NotConnected,
67                ServerError::CommandChannelClosed
68                | ServerError::AcceptChannelClosed
69                | ServerError::WorkerStopped => io::ErrorKind::BrokenPipe,
70                ServerError::Io { .. } | ServerError::InvalidConfig { .. } => {
71                    io::ErrorKind::InvalidInput
72                }
73            };
74            io::Error::new(kind, value.to_string())
75        }
76    }
77}
78
79#[derive(Debug, Error)]
80pub enum EncodeError {
81    #[error("missing reliable index for reliable frame")]
82    MissingReliableIndex,
83    #[error("missing sequence index for sequenced frame")]
84    MissingSequenceIndex,
85    #[error("missing ordering index for ordered/sequenced frame")]
86    MissingOrderingIndex,
87    #[error("missing ordering channel for ordered/sequenced frame")]
88    MissingOrderingChannel,
89    #[error("missing split metadata for split frame")]
90    MissingSplitInfo,
91    #[error("frame payload length does not match bit length")]
92    FrameBitLengthMismatch,
93    #[error("ack/nack record count overflow: {0}")]
94    AckRecordOverflow(usize),
95    #[error("mtu out of supported range: {0}")]
96    InvalidMtu(u16),
97    #[error("offline pong motd is too long: {0} bytes")]
98    OfflinePongMotdTooLong(usize),
99    #[error("invalid datagram flags: 0x{0:02x}")]
100    InvalidDatagramFlags(u8),
101}
102
103#[derive(Debug, Error)]
104pub enum DecodeError {
105    #[error("unexpected eof")]
106    UnexpectedEof,
107    #[error("unknown reliability value: {0}")]
108    UnknownReliability(u8),
109    #[error("invalid frame bit length: {0}")]
110    InvalidFrameBitLength(u16),
111    #[error("invalid ack packet")]
112    InvalidAckPacket,
113    #[error("invalid datagram flags: 0x{0:02x}")]
114    InvalidDatagramFlags(u8),
115    #[error("invalid offline packet id: 0x{0:02x}")]
116    InvalidOfflinePacketId(u8),
117    #[error("invalid connected packet id: 0x{0:02x}")]
118    InvalidConnectedPacketId(u8),
119    #[error("invalid magic for unconnected packet")]
120    InvalidMagic,
121    #[error("invalid ip address version: {0}")]
122    InvalidAddrVersion(u8),
123    #[error("invalid open connection request 2 layout")]
124    InvalidRequest2Layout,
125    #[error("split index out of range")]
126    SplitIndexOutOfRange,
127    #[error("split count cannot be zero")]
128    SplitCountZero,
129    #[error("split metadata missing while split flag is set")]
130    MissingSplitInfo,
131    #[error("split count mismatch")]
132    SplitCountMismatch,
133    #[error("split packet exceeds maximum part limit")]
134    SplitTooLarge,
135    #[error("split assembler buffer is full")]
136    SplitBufferFull,
137    #[error("invalid ack range count: {0}")]
138    InvalidAckRangeCount(u16),
139}