krabka_client_coordination/error.rs
1//! The error type of the coordination client.
2
3use krabka_client_admin::AdminError;
4use krabka_client_core::ClientError;
5use krabka_client_producer::ProducerError;
6use thiserror::Error;
7
8use crate::record::{MemberId, RecordError, Role};
9
10/// A fault that the coordination client reports.
11#[derive(Debug, Error)]
12#[non_exhaustive]
13pub enum CoordinationError {
14 /// A record of the coordination topic did not decode, or a name did not
15 /// pass its constructor.
16 #[error("record: {0}")]
17 Record(#[from] RecordError),
18
19 /// The connection layer failed.
20 #[error("client: {0}")]
21 Client(#[from] ClientError),
22
23 /// The producer failed for a reason other than a fence.
24 #[error("producer: {0}")]
25 Producer(#[from] ProducerError),
26
27 /// The admin client failed.
28 #[error("admin: {0}")]
29 Admin(#[from] AdminError),
30
31 /// The broker fenced this member, so another member holds the role now.
32 ///
33 /// This is the expected end of a leadership. The caller stops the work of
34 /// the role at once. The epoch it held is superseded, so the cluster
35 /// already rejects every write it makes.
36 #[error("fenced: another member holds role {role}")]
37 Fenced {
38 /// The role that this member no longer holds.
39 role: Role,
40 },
41
42 /// The caller asked a leadership handle to act after it resigned.
43 #[error("member {member} no longer holds role {role}")]
44 NotHeld {
45 /// The role that the handle named.
46 role: Role,
47 /// The member that the handle named.
48 member: MemberId,
49 },
50
51 /// The acquire call reached its deadline before this member won the role.
52 ///
53 /// Another member held the role for the whole wait. A caller that must
54 /// keep waiting calls acquire again.
55 #[error("did not win role {role} before the deadline")]
56 AcquireTimeout {
57 /// The role that this member competed for.
58 role: Role,
59 },
60
61 /// A configuration value is outside the range that the client accepts.
62 #[error("invalid config: {0}")]
63 InvalidConfig(String),
64}
65
66impl CoordinationError {
67 /// Report whether the broker fenced this member.
68 ///
69 /// A caller uses this to separate the loss of a role, which is an ordinary
70 /// event, from a fault that a retry could clear.
71 #[must_use]
72 pub fn is_fenced(&self) -> bool {
73 matches!(
74 self,
75 Self::Fenced { .. } | Self::Producer(ProducerError::FencedProducer)
76 )
77 }
78}