Skip to main content

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}