Skip to main content

mssql_codec/
error.rs

1//! Codec error types.
2
3use thiserror::Error;
4
5/// Errors that can occur during packet encoding/decoding.
6#[derive(Debug, Error)]
7#[non_exhaustive]
8pub enum CodecError {
9    /// IO error during read/write operations.
10    #[error("IO error: {0}")]
11    Io(#[from] std::io::Error),
12
13    /// Protocol-level error from tds-protocol.
14    #[error("protocol error: {0}")]
15    Protocol(#[from] tds_protocol::ProtocolError),
16
17    /// Packet too large.
18    #[error("packet too large: {size} bytes (max {max})")]
19    PacketTooLarge {
20        /// Actual packet size.
21        size: usize,
22        /// Maximum allowed size.
23        max: usize,
24    },
25
26    /// Assembled response message exceeded the configured size limit.
27    #[error("response message too large: {size} bytes exceeds the {limit}-byte limit")]
28    MessageTooLarge {
29        /// Bytes accumulated when the limit was exceeded.
30        size: usize,
31        /// The configured limit.
32        limit: usize,
33    },
34
35    /// Incomplete packet data.
36    #[error("incomplete packet: need {needed} more bytes")]
37    IncompletePacket {
38        /// Bytes needed to complete the packet.
39        needed: usize,
40    },
41
42    /// Invalid packet header.
43    #[error("invalid packet header")]
44    InvalidHeader,
45
46    /// Connection closed unexpectedly.
47    #[error("connection closed")]
48    ConnectionClosed,
49
50    /// The in-flight request was cancelled via an Attention signal and the
51    /// server acknowledged the cancellation (DONE_ATTN). The connection is
52    /// drained and remains usable for new requests.
53    #[error("request cancelled")]
54    Cancelled,
55
56    /// Encoding error.
57    #[error("encoding error: {0}")]
58    Encoding(String),
59
60    /// Decoding error.
61    #[error("decoding error: {0}")]
62    Decoding(String),
63}
64
65impl CodecError {
66    /// Check if this error is transient and may succeed on retry.
67    ///
68    /// IO errors and connection closures are typically transient.
69    /// Protocol, encoding, and header errors are terminal.
70    #[must_use]
71    pub fn is_transient(&self) -> bool {
72        match self {
73            Self::Io(_) | Self::ConnectionClosed => true,
74            Self::Protocol(e) => e.is_transient(),
75            _ => false,
76        }
77    }
78
79    /// Check if this error is terminal and will never succeed on retry.
80    #[must_use]
81    pub fn is_terminal(&self) -> bool {
82        !self.is_transient()
83    }
84}