Skip to main content

kacrab_protocol/
error.rs

1//! Top-level protocol error — a thin facade over the per-module error types.
2//!
3//! Every module under this crate has its own error in `foo/error.rs`. This
4//! enum lifts those into one type via `#[from]` so callers that cross several
5//! layers can keep using `?` without bespoke conversions.
6//!
7//! Authors of new fallible code should prefer returning the **module's own**
8//! error and let `#[from]` handle the lift; reserve direct construction of
9//! [`ProtocolError`] for the crate boundary (lib facade, generated code).
10
11use crate::{
12    bytes_io::BytesError,
13    compression::CompressionError,
14    crc::CrcMismatch,
15    frame::FrameError,
16    primitives::PrimitiveError,
17    record::RecordError,
18    string::StringError,
19    tagged::TaggedFieldError,
20    uuid::UuidError,
21    version::{UnsupportedFieldVersion, UnsupportedVersion},
22};
23
24/// Convenience alias for `Result<T, ProtocolError>`.
25pub type Result<T> = core::result::Result<T, ProtocolError>;
26
27/// Crate-wide error facade. Every module error converts in via `#[from]`.
28///
29/// # Why a facade and not a single big enum?
30///
31/// Module errors stay narrow — callers that only deal with primitives won't be
32/// forced to `match` a `RecordError` variant they can't produce. The facade
33/// only widens at the boundary where errors need to flow uniformly (e.g. the
34/// generated message decoders).
35#[derive(Debug, thiserror::Error)]
36#[non_exhaustive]
37pub enum ProtocolError {
38    /// Primitive int / varint / array-length read failed.
39    #[error(transparent)]
40    Primitive(#[from] PrimitiveError),
41
42    /// Length-prefixed raw bytes read/write failed.
43    #[error(transparent)]
44    Bytes(#[from] BytesError),
45
46    /// `KafkaString` read/write failed (length, UTF-8, null marker).
47    #[error(transparent)]
48    String(#[from] StringError),
49
50    /// `KafkaUuid` parse failed.
51    #[error(transparent)]
52    Uuid(#[from] UuidError),
53
54    /// Tagged-fields section is malformed (out-of-order tag, bad size).
55    #[error(transparent)]
56    Tagged(#[from] TaggedFieldError),
57
58    /// CRC32C check failed on a record batch.
59    #[error(transparent)]
60    Crc(#[from] CrcMismatch),
61
62    /// TCP frame length prefix is invalid or oversized.
63    #[error(transparent)]
64    Frame(#[from] FrameError),
65
66    /// Record batch decode failed (CRC, magic, length, record count).
67    #[error(transparent)]
68    Record(#[from] RecordError),
69
70    /// Compression codec dispatch / encode / decode failed.
71    #[error(transparent)]
72    Compression(#[from] CompressionError),
73
74    /// API key / version negotiation failed.
75    #[error(transparent)]
76    Version(#[from] UnsupportedVersion),
77
78    /// A generated message field was set for a version where it is absent.
79    #[error(transparent)]
80    FieldVersion(#[from] UnsupportedFieldVersion),
81}