1use std::fmt;
4
5pub type RaftResult<T> = Result<T, RaftError>;
7
8#[derive(Debug, Clone, PartialEq)]
10pub enum RaftError {
11 NotLeader {
13 leader_id: Option<u64>,
15 },
16 InvalidState {
18 expected: String,
20 actual: String,
22 },
23 LogInconsistency {
25 reason: String,
27 },
28 StorageError {
30 message: String,
32 },
33 StaleTerm {
35 current: u64,
37 received: u64,
39 },
40 VoteAlreadyGranted {
42 voted_for: u64,
44 },
45 ConfigError {
47 message: String,
49 },
50 NetworkError {
52 message: String,
54 },
55 Timeout {
57 description: String,
59 },
60 MembershipChangeInProgress,
62 NodeAlreadyMember {
64 node_id: u64,
66 },
67 NodeNotMember {
69 node_id: u64,
71 },
72 StateMachineError {
74 message: String,
76 },
77 Recovering,
79 Other {
81 message: String,
83 },
84}
85
86impl fmt::Display for RaftError {
87 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88 match self {
89 RaftError::NotLeader { leader_id } => {
90 write!(f, "Not leader")?;
91 if let Some(id) = leader_id {
92 write!(f, " (current leader: {})", id)?;
93 }
94 Ok(())
95 }
96 RaftError::InvalidState { expected, actual } => {
97 write!(f, "Invalid state: expected {}, got {}", expected, actual)
98 }
99 RaftError::LogInconsistency { reason } => {
100 write!(f, "Log inconsistency: {}", reason)
101 }
102 RaftError::StorageError { message } => {
103 write!(f, "Storage error: {}", message)
104 }
105 RaftError::StaleTerm { current, received } => {
106 write!(f, "Stale term: current {}, received {}", current, received)
107 }
108 RaftError::VoteAlreadyGranted { voted_for } => {
109 write!(f, "Vote already granted to node {}", voted_for)
110 }
111 RaftError::ConfigError { message } => {
112 write!(f, "Configuration error: {}", message)
113 }
114 RaftError::NetworkError { message } => {
115 write!(f, "Network error: {}", message)
116 }
117 RaftError::Timeout { description } => {
118 write!(f, "Timeout: {}", description)
119 }
120 RaftError::MembershipChangeInProgress => {
121 write!(
122 f,
123 "A membership change is already in progress (joint consensus active)"
124 )
125 }
126 RaftError::NodeAlreadyMember { node_id } => {
127 write!(f, "Node {} is already a member of the cluster", node_id)
128 }
129 RaftError::NodeNotMember { node_id } => {
130 write!(f, "Node {} is not a member of the cluster", node_id)
131 }
132 RaftError::StateMachineError { message } => {
133 write!(f, "State machine error: {}", message)
134 }
135 RaftError::Recovering => {
136 write!(
137 f,
138 "Node is replaying WAL on startup and cannot serve requests"
139 )
140 }
141 RaftError::Other { message } => {
142 write!(f, "Error: {}", message)
143 }
144 }
145 }
146}
147
148impl std::error::Error for RaftError {}