Skip to main content

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}