ghast_client/error.rs
1//! Errors and session outcomes.
2
3use ghast_protocol::{DecodeError, EncodeError, FrameError, State};
4use thiserror::Error;
5
6/// How a session that reached the play state ended without an error.
7#[derive(Debug, Clone, PartialEq, Eq)]
8#[non_exhaustive]
9pub enum SessionEnd {
10 /// The server kicked the player.
11 Kicked {
12 /// The reason as plain text.
13 reason: String,
14 /// The reason as the server sent it (chat JSON).
15 json: String,
16 },
17 /// The server closed the connection without a reason.
18 ServerClosed,
19 /// The behaviour called [`crate::TickContext::disconnect`].
20 Quit(String),
21 /// The shutdown future given to [`crate::Client::run_until`] completed.
22 Shutdown,
23}
24
25/// A session failed.
26#[derive(Debug, Error)]
27#[non_exhaustive]
28pub enum ClientError {
29 /// Opening the connection (direct or through the proxy) failed.
30 #[error(transparent)]
31 Connect(#[from] ghast_auth::connect::ConnectError),
32 /// The username is not valid for an offline login.
33 #[error("invalid username: {0}")]
34 Username(#[from] ghast_auth::offline::UsernameError),
35 /// Socket error.
36 #[error("connection error: {0}")]
37 Io(#[from] std::io::Error),
38 /// Framing / compression / encryption error (the stream is unusable).
39 #[error("bad frame from the server: {0}")]
40 Frame(#[source] FrameError),
41 /// A packet the client needs could not be decoded.
42 #[error("could not decode {state:?} packet 0x{id:02x}: {source}")]
43 Decode {
44 /// Connection state.
45 state: State,
46 /// Packet id.
47 id: i32,
48 /// What was wrong.
49 #[source]
50 source: DecodeError,
51 },
52 /// Chunk data from the server was malformed. Since 0.1.3 a session no longer ends with
53 /// it: the column is dropped, the error logged and play goes on (like vanilla). Kept for
54 /// compatibility.
55 #[error("bad chunk data: {0}")]
56 World(#[source] ghast_world::WorldError),
57 /// A packet could not be encoded (a value the protocol cannot carry).
58 #[error("could not encode a packet: {0}")]
59 Encode(#[from] EncodeError),
60 /// The server refused the login.
61 #[error("login refused: {0}")]
62 LoginRefused(String),
63 /// The server closed the connection during login.
64 #[error("the server closed the connection during login")]
65 LoginClosed,
66 /// The server is in online mode but the account is an offline one.
67 #[error("the server requires online mode (a Microsoft account)")]
68 OnlineModeRequired,
69 /// The encryption handshake failed.
70 #[error("encryption handshake: {0}")]
71 Crypto(#[from] ghast_auth::crypto::CryptoError),
72 /// The session server refused the join (online mode).
73 #[cfg(feature = "microsoft")]
74 #[error("session server: {0}")]
75 Session(#[from] ghast_auth::microsoft::MicrosoftError),
76 /// No data from the server for too long.
77 #[error("timed out: {0}")]
78 Timeout(&'static str),
79}
80
81impl From<FrameError> for ClientError {
82 fn from(e: FrameError) -> Self {
83 match e {
84 FrameError::Io(io) => ClientError::Io(io),
85 e => ClientError::Frame(e),
86 }
87 }
88}