tds_protocol/error.rs
1//! Protocol-level error types.
2
3use thiserror::Error;
4
5/// Errors that can occur during TDS protocol parsing or encoding.
6#[derive(Debug, Error)]
7#[non_exhaustive]
8pub enum ProtocolError {
9 /// Packet data is truncated or incomplete.
10 #[error("incomplete packet: expected {expected} bytes, got {actual}")]
11 IncompletePacket {
12 /// Expected number of bytes.
13 expected: usize,
14 /// Actual number of bytes available.
15 actual: usize,
16 },
17
18 /// Invalid packet type value.
19 #[error("invalid packet type: {0:#x}")]
20 InvalidPacketType(u8),
21
22 /// Invalid token type value.
23 #[error("invalid token type: {0:#x}")]
24 InvalidTokenType(u8),
25
26 /// Invalid data type value.
27 #[error("invalid data type: {0:#x}")]
28 InvalidDataType(u8),
29
30 /// Invalid prelogin option.
31 #[error("invalid prelogin option: {0:#x}")]
32 InvalidPreloginOption(u8),
33
34 /// Invalid TDS version.
35 #[error("invalid TDS version: {0:#x}")]
36 InvalidTdsVersion(u32),
37
38 /// String encoding error.
39 #[error("string encoding error: {0}")]
40 StringEncoding(
41 #[cfg(feature = "std")] String,
42 #[cfg(not(feature = "std"))] &'static str,
43 ),
44
45 /// Packet length exceeds maximum allowed.
46 #[error("packet too large: {length} bytes (max {max})")]
47 PacketTooLarge {
48 /// Actual packet length.
49 length: usize,
50 /// Maximum allowed length.
51 max: usize,
52 },
53
54 /// Invalid packet status flags.
55 #[error("invalid packet status: {0:#x}")]
56 InvalidPacketStatus(u8),
57
58 /// Buffer overflow during encoding.
59 #[error("buffer overflow: needed {needed} bytes, capacity {capacity}")]
60 BufferOverflow {
61 /// Bytes needed.
62 needed: usize,
63 /// Buffer capacity.
64 capacity: usize,
65 },
66
67 /// Unexpected end of stream.
68 #[error("unexpected end of stream")]
69 UnexpectedEof,
70
71 /// Protocol version mismatch.
72 #[error("unsupported protocol version: {0}")]
73 UnsupportedVersion(u32),
74
75 /// Invalid field value in a protocol structure.
76 #[error("invalid {field} value: {value}")]
77 InvalidField {
78 /// Field name.
79 field: &'static str,
80 /// Invalid value.
81 value: u32,
82 },
83}
84
85impl ProtocolError {
86 /// Check if this error is transient and may succeed on retry.
87 ///
88 /// Protocol errors are almost always terminal — they indicate malformed data
89 /// or driver bugs. The only transient case is `UnexpectedEof`, which may
90 /// occur during connection loss.
91 #[must_use]
92 pub fn is_transient(&self) -> bool {
93 matches!(self, Self::UnexpectedEof)
94 }
95
96 /// Check if this error is terminal and will never succeed on retry.
97 ///
98 /// Most protocol errors indicate a fundamental mismatch between client
99 /// and server, a driver bug, or corrupted data.
100 #[must_use]
101 pub fn is_terminal(&self) -> bool {
102 !self.is_transient()
103 }
104}