krabka_remote_storage_topic/error.rs
1//! Errors surfaced by the topic-backed
2//! [`RemoteLogMetadataManager`](krabka_remote_storage::RemoteLogMetadataManager)
3//! and the underlying [`MetadataEventLog`](crate::MetadataEventLog).
4
5use {krabka_remote_storage::RemoteStorageError, std::io};
6
7/// Failures from the publish/subscribe transport that backs the
8/// `__remote_log_metadata` topic.
9#[derive(Debug, thiserror::Error)]
10pub enum MetadataLogError {
11 /// The transport refused the publish, for example because the broker
12 /// was unreachable or the ack timed out. The log did not append the
13 /// event.
14 #[error("publish failed: {0}")]
15 Publish(String),
16
17 /// Asked about a partition outside `[0, partition_count())`.
18 #[error("metadata partition {partition} out of range (count {count})")]
19 PartitionOutOfRange {
20 /// The offending partition index.
21 partition: i32,
22 /// The configured partition count.
23 count: i32,
24 },
25
26 /// The `__remote_log_metadata` partition count is not positive, so no
27 /// user partition maps to a metadata partition.
28 #[error("metadata partition count {count} is not positive")]
29 NonPositivePartitionCount {
30 /// The configured partition count.
31 count: i32,
32 },
33
34 /// The transport is closed and no further operations are possible.
35 #[error("metadata log closed")]
36 Closed,
37
38 /// Any other transport-layer failure.
39 #[error("metadata log error: {0}")]
40 Other(String),
41}
42
43impl MetadataLogError {
44 /// Wrap as a [`RemoteStorageError`] so the manager can surface
45 /// transport failures through the synchronous SPI.
46 #[must_use]
47 pub fn into_storage(self) -> RemoteStorageError {
48 RemoteStorageError::Io(io::Error::other(self.to_string()))
49 }
50}
51
52/// Errors from the binary wire codec.
53#[derive(Debug, thiserror::Error)]
54pub enum CodecError {
55 /// The buffer ended before the parser had finished a field.
56 #[error("unexpected end of input at offset {0}")]
57 UnexpectedEof(usize),
58
59 /// A state byte the codec does not know how to read.
60 #[error("unknown state byte {0} for {ctx}", ctx = .1)]
61 UnknownState(u8, &'static str),
62
63 /// A length prefix that does not fit in `usize`.
64 #[error("length prefix {0} too large")]
65 LengthOverflow(u64),
66
67 /// The reconstruction of the event-domain type from the decoded fields
68 /// violated a precondition, for example an empty leader-epoch map.
69 #[error("decoded event rejected: {0}")]
70 Domain(String),
71
72 /// An error propagated from the generated protocol codec: envelope
73 /// framing, schema mismatch, or trailing bytes.
74 #[error("protocol codec: {0}")]
75 Protocol(String),
76}
77
78/// Errors from the on-disk RLMM snapshot.
79#[derive(Debug, thiserror::Error)]
80pub enum SnapshotError {
81 /// The snapshot file could not be read or written.
82 #[error("snapshot io error: {0}")]
83 Io(#[from] io::Error),
84
85 /// A snapshot format version the loader does not understand.
86 #[error("unsupported snapshot format version {0}")]
87 UnsupportedVersion(u16),
88
89 /// The snapshot bytes were malformed. They were truncated, badly framed,
90 /// or a contained event failed to decode.
91 #[error("malformed snapshot: {0}")]
92 Malformed(#[from] CodecError),
93
94 /// Trailing bytes remained after the declared entries were read.
95 #[error("snapshot has {0} trailing bytes")]
96 TrailingBytes(usize),
97}