ghast_protocol/error.rs
1//! Error types.
2//!
3//! Decoding works on untrusted bytes from the network, so every failure is a value of
4//! [`DecodeError`]; nothing in the decode path panics.
5
6use thiserror::Error;
7
8/// Failure while decoding a value from bytes.
9#[derive(Debug, Clone, PartialEq, Eq, Error)]
10#[non_exhaustive]
11pub enum DecodeError {
12 /// The input ended before the value was complete.
13 #[error("unexpected end of input: needed {needed} more byte(s)")]
14 UnexpectedEof {
15 /// How many more bytes the reader wanted (at least).
16 needed: usize,
17 },
18 /// A VarInt was longer than 5 bytes (or a VarLong longer than 10).
19 #[error("VarInt/VarLong is too long")]
20 VarIntTooLong,
21 /// A length prefix was negative.
22 #[error("negative length {0}")]
23 NegativeLength(i64),
24 /// A length prefix was larger than the remaining input or a configured limit.
25 #[error("length {len} exceeds limit {limit}")]
26 LengthTooLarge {
27 /// The declared length.
28 len: usize,
29 /// The limit it exceeded.
30 limit: usize,
31 },
32 /// A string was not valid UTF-8 (or NBT Modified UTF-8).
33 #[error("invalid UTF-8 in string")]
34 InvalidUtf8,
35 /// An NBT tag id was not a known tag type.
36 #[error("invalid NBT tag type {0}")]
37 InvalidNbtTag(u8),
38 /// NBT nested deeper than the allowed limit.
39 #[error("NBT nesting deeper than {0}")]
40 NbtTooDeep(usize),
41 /// An NBT list declared elements of type End with a non-zero length.
42 #[error("NBT list of TAG_End with non-zero length")]
43 NbtEndList,
44 /// A value that is not allowed by the format (e.g. an empty top-bit-terminated array).
45 #[error("invalid value: {0}")]
46 Invalid(&'static str),
47 /// Bytes were left over after a packet body was decoded.
48 #[error("{0} trailing byte(s) after packet")]
49 TrailingBytes(usize),
50 /// The packet id is not known for this state/direction/version.
51 #[error("unknown packet id 0x{0:02x}")]
52 UnknownPacketId(i32),
53 /// A typed decode was requested for a packet with a different id.
54 #[error("packet id mismatch: expected 0x{expected:02x}, got 0x{actual:02x}")]
55 IdMismatch {
56 /// Id of the requested packet type.
57 expected: i32,
58 /// Id of the raw packet.
59 actual: i32,
60 },
61}
62
63/// Failure while encoding a value.
64#[derive(Debug, Clone, PartialEq, Eq, Error)]
65#[non_exhaustive]
66pub enum EncodeError {
67 /// A length does not fit the length prefix type (e.g. more than `i16::MAX` items).
68 #[error("length {len} does not fit the length prefix (max {max})")]
69 LengthOverflow {
70 /// The actual length.
71 len: usize,
72 /// The largest length the prefix can carry.
73 max: usize,
74 },
75 /// A fixed-length array or a field-counted array has the wrong number of elements.
76 #[error("field `{field}`: expected {expected} element(s), got {actual}")]
77 CountMismatch {
78 /// Field path.
79 field: &'static str,
80 /// Count required by the format or by the counting field.
81 expected: usize,
82 /// Actual element count.
83 actual: usize,
84 },
85 /// A conditional field does not match its discriminant (e.g. `Some` where the
86 /// discriminant says the field is absent, or the wrong enum variant).
87 #[error("field `{0}` does not match its discriminant")]
88 SwitchMismatch(&'static str),
89 /// A value does not fit its bit field or packed representation.
90 #[error("field `{0}` is out of range for its encoding")]
91 OutOfRange(&'static str),
92 /// A value that the format cannot represent.
93 #[error("invalid value: {0}")]
94 Invalid(&'static str),
95}
96
97/// Failure in the framing layer (length prefix, compression, encryption).
98#[derive(Debug, Error)]
99#[non_exhaustive]
100pub enum FrameError {
101 /// The frame length prefix is malformed (more than 3 bytes, negative, or zero).
102 #[error("bad frame length prefix")]
103 BadLength,
104 /// The frame is larger than the configured maximum.
105 #[error("frame of {len} bytes exceeds maximum {max}")]
106 FrameTooLarge {
107 /// Declared frame length.
108 len: usize,
109 /// Configured limit.
110 max: usize,
111 },
112 /// The declared uncompressed size is larger than the configured maximum.
113 #[error("decompressed size {len} exceeds maximum {max}")]
114 DecompressedTooLarge {
115 /// Declared uncompressed length.
116 len: usize,
117 /// Configured limit.
118 max: usize,
119 },
120 /// The zlib stream was corrupt or did not inflate to exactly the declared size.
121 #[error("bad compressed packet: {0}")]
122 BadCompression(&'static str),
123 /// The frame contents could not be decoded (packet id or data-length VarInt).
124 #[error(transparent)]
125 Decode(#[from] DecodeError),
126 /// I/O error from the underlying transport.
127 #[error(transparent)]
128 Io(#[from] std::io::Error),
129}