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}