nodedb_cluster/swim/
error.rs1use thiserror::Error;
9
10use nodedb_types::NodeId;
11
12use super::incarnation::Incarnation;
13use super::member::MemberState;
14
15#[derive(Debug, Error)]
17pub enum SwimError {
18 #[error("swim: unknown member {node_id}")]
22 UnknownMember { node_id: NodeId },
23
24 #[error("swim: stale incarnation for {node_id}: received {received:?} <= local {local:?}")]
27 StaleIncarnation {
28 node_id: NodeId,
29 received: Incarnation,
30 local: Incarnation,
31 },
32
33 #[error("swim: local node suspected at incarnation {incarnation:?}")]
37 SelfSuspected { incarnation: Incarnation },
38
39 #[error("swim: invalid state transition {from:?} -> {to:?}")]
42 InvalidTransition { from: MemberState, to: MemberState },
43
44 #[error("swim: invalid config field {field}: {reason}")]
46 InvalidConfig {
47 field: &'static str,
48 reason: &'static str,
49 },
50
51 #[error("swim: encode failure: {detail}")]
55 Encode { detail: String },
56
57 #[error("swim: decode failure: {detail}")]
60 Decode { detail: String },
61}
62
63impl From<SwimError> for crate::error::ClusterError {
64 fn from(err: SwimError) -> Self {
65 crate::error::ClusterError::Transport {
66 detail: err.to_string(),
67 }
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn display_contains_context() {
77 let err = SwimError::StaleIncarnation {
78 node_id: NodeId::new("n1"),
79 received: Incarnation::new(3),
80 local: Incarnation::new(5),
81 };
82 let msg = err.to_string();
83 assert!(msg.contains("n1"));
84 assert!(msg.contains('3'));
85 assert!(msg.contains('5'));
86 }
87
88 #[test]
89 fn invalid_config_display() {
90 let err = SwimError::InvalidConfig {
91 field: "probe_timeout",
92 reason: "must be strictly less than probe_interval",
93 };
94 assert!(err.to_string().contains("probe_timeout"));
95 }
96
97 #[test]
98 fn bridges_to_cluster_error() {
99 let err: crate::error::ClusterError = SwimError::UnknownMember {
100 node_id: NodeId::new("n42"),
101 }
102 .into();
103 assert!(matches!(err, crate::error::ClusterError::Transport { .. }));
104 }
105}