mc_query/
errors.rs

1//! All the errors defined by this crate.
2
3use std::io::{self, ErrorKind};
4use thiserror::Error;
5
6/// An error from the Minecraft networking protocol.
7#[derive(Error, Debug)]
8pub enum MinecraftProtocolError {
9    /// `VarInt` data was invalid according to the spec.
10    #[error("invalid varint data")]
11    InvalidVarInt,
12
13    /// Received invalid state information from the server.
14    #[error("invalid state")]
15    InvalidState,
16
17    /// Received incorrectly formatted status response from the server.
18    #[error("invalid status response")]
19    InvalidStatusResponse,
20}
21
22impl From<MinecraftProtocolError> for io::Error {
23    fn from(err: MinecraftProtocolError) -> Self {
24        io::Error::new(ErrorKind::InvalidData, err)
25    }
26}
27
28/// An error from the RCON protocol.
29#[derive(Error, Debug)]
30pub enum RconProtocolError {
31    /// Received non-ASCII payload data from the server.
32    ///
33    /// Note: some servers (for example Craftbukkit for Minecraft 1.4.7) reply
34    /// with the section sign (0xa7) as a prefix for the payload. This error
35    /// will not be returned in that case.
36    #[error("non-ascii payload")]
37    NonAsciiPayload,
38
39    /// Authentication failed. You probably entered the wrong RCON password.
40    #[error("authentication failed")]
41    AuthFailed,
42
43    /// Invalid or unexpected packet type received from the server.
44    #[error("invalid packet type")]
45    InvalidPacketType,
46
47    /// Other kind of invalid response as defined by the spec.
48    #[error("invalid rcon response")]
49    InvalidRconResponse,
50
51    /// Payload too long.
52    ///
53    /// | Direction   | Payload Length limit |
54    /// | ----------- | -------------------- |
55    /// | Serverbound | 1446                 |
56    /// | Clientbound | 4096                 |
57    #[error("payload too long")]
58    PayloadTooLong,
59
60    /// Mismatch with the given request ID.
61    ///
62    /// Note: the server replies with a request ID of -1 in the case of an
63    /// authentication failure. In that case, `AuthFailed` will be returned.
64    /// This variant is returned if any *other* request ID was received.
65    #[error("request id mismatch")]
66    RequestIdMismatch,
67}
68
69impl From<RconProtocolError> for io::Error {
70    fn from(err: RconProtocolError) -> Self {
71        io::Error::new(ErrorKind::InvalidData, err)
72    }
73}
74
75/// An error from the Query protocol.
76#[derive(Error, Debug)]
77pub enum QueryProtocolError {
78    /// Received invalid packet type.
79    /// Valid types are 9 for handshake, 0 for stat
80    #[error("invalid packet type")]
81    InvalidPacketType,
82
83    /// Unexpected packet type.
84    #[error("unexpected packet type")]
85    UnexpectedPacketType,
86
87    /// Mismatch with the generated session ID.
88    #[error("session id mismatch")]
89    SessionIdMismatch,
90
91    /// Received invalid challenge token from server.
92    #[error("invalid challenge token")]
93    InvalidChallengeToken,
94
95    /// Invalid integer.
96    /// Did not receive valid characters to parse as an integer in the string
97    #[error("cannot parse int")]
98    CannotParseInt,
99
100    /// Invalid UTF8.
101    /// Did not receive valid UTF from the server when a string was expected
102    #[error("invalid UTF-8")]
103    InvalidUtf8,
104
105    /// Invalid key/value section.
106    /// Expecting something like [this](https://wiki.vg/Query#K.2C_V_section)
107    #[error("invalid key/value section")]
108    InvalidKeyValueSection,
109}
110
111impl From<QueryProtocolError> for io::Error {
112    fn from(err: QueryProtocolError) -> Self {
113        io::Error::new(ErrorKind::InvalidData, err)
114    }
115}
116
117pub(crate) fn timeout_err<T>() -> io::Result<T> {
118    Err(io::Error::new(ErrorKind::TimedOut, "connection timed out"))
119}