crabka_remote_storage/error.rs
1//! Error type shared by both tiered-storage SPIs.
2
3use crate::metadata::{
4 RemoteLogSegmentId, RemoteLogSegmentState, RemotePartitionDeleteState, TopicIdPartition,
5};
6
7/// Errors raised by [`RemoteStorageManager`](crate::RemoteStorageManager)
8/// and [`RemoteLogMetadataManager`](crate::RemoteLogMetadataManager)
9/// implementations.
10#[derive(Debug, thiserror::Error)]
11pub enum RemoteStorageError {
12 /// An I/O failure in the underlying store (filesystem, object store, …).
13 #[error("remote storage I/O error: {0}")]
14 Io(#[from] std::io::Error),
15
16 /// A segment was referenced that the metadata store has never seen.
17 #[error("no remote log segment metadata for {0:?}")]
18 SegmentNotFound(RemoteLogSegmentId),
19
20 /// `add_remote_log_segment_metadata` was called with a starting state
21 /// other than [`RemoteLogSegmentState::CopySegmentStarted`], or for a
22 /// segment id that already exists.
23 #[error("invalid add for {id:?}: {reason}")]
24 InvalidAdd {
25 /// The offending segment id.
26 id: RemoteLogSegmentId,
27 /// Why the add was rejected.
28 reason: String,
29 },
30
31 /// A lifecycle transition was requested that the state machine forbids.
32 #[error("invalid segment state transition for {id:?}: {from:?} -> {to:?}")]
33 InvalidSegmentTransition {
34 /// The segment whose transition was rejected.
35 id: RemoteLogSegmentId,
36 /// Current state.
37 from: RemoteLogSegmentState,
38 /// Requested state.
39 to: RemoteLogSegmentState,
40 },
41
42 /// A partition-delete lifecycle transition was requested that the
43 /// state machine forbids.
44 #[error("invalid partition delete transition for {tp:?}: {from:?} -> {to:?}")]
45 InvalidPartitionDeleteTransition {
46 /// The partition whose transition was rejected.
47 tp: TopicIdPartition,
48 /// Current state (`None` when the partition was never marked).
49 from: Option<RemotePartitionDeleteState>,
50 /// Requested state.
51 to: RemotePartitionDeleteState,
52 },
53
54 /// Constructor / argument validation failed.
55 #[error("invalid argument: {0}")]
56 InvalidArgument(String),
57
58 /// A backend (e.g. an object store) raised an error that doesn't map
59 /// cleanly to one of the structured variants above.
60 #[error("remote storage backend error: {0}")]
61 Backend(String),
62
63 /// The metadata partition that would answer this query is assigned to
64 /// this broker but its consumer has not yet caught up to the high-water
65 /// mark observed when the partition was assigned. The answer is unknown,
66 /// not "no segment" — callers should retry rather than treat it as a
67 /// definitive miss. `Ok(None)` is reserved for "caught up, no covering
68 /// segment" and for partitions this broker does not consume at all.
69 #[error("remote log metadata partition {partition} not ready (assigned but not caught up)")]
70 NotReady {
71 /// The `__remote_log_metadata` partition that is still catching up.
72 partition: i32,
73 },
74}