test_semantic/
error.rs

1//! Definitions central to BPCon errors.
2
3use crate::party::{PartyEvent, PartyStatus};
4use crate::value::Value;
5use thiserror::Error;
6
7/// Represents the various errors that can occur during the ballot launch process.
8#[derive(Error, Debug)]
9pub enum LaunchBallotError {
10    /// Occurs when an attempt to send a `PartyEvent` fails.
11    ///
12    /// - `0`: The `PartyEvent` that failed to send.
13    /// - `1`: A string detailing the specific failure reason.
14    #[error("failed to send event {0}: {1}")]
15    FailedToSendEvent(PartyEvent, String),
16
17    /// Occurs when the event channel is unexpectedly closed.
18    #[error("event channel closed")]
19    EventChannelClosed,
20
21    /// Occurs when the message channel is unexpectedly closed.
22    #[error("message channel closed")]
23    MessageChannelClosed,
24
25    /// Occurs when following a `PartyEvent` fails.
26    ///
27    /// - `0`: The `PartyEvent` that caused the error.
28    /// - `1`: The specific `FollowEventError` detailing why the follow operation failed.
29    #[error("failed to follow event {0}: {1}")]
30    FollowEventError(PartyEvent, FollowEventError),
31
32    /// Occurs during leader election if an error is encountered.
33    ///
34    /// - `0`: A string providing details about the leader election failure.
35    #[error("leader election error: {0}")]
36    LeaderElectionError(String),
37}
38
39/// Represents the various errors that can occur while following a party event.
40#[derive(Error, Debug)]
41pub enum FollowEventError {
42    /// Occurs when there is a mismatch in the expected party status.
43    ///
44    /// - `0`: The specific `PartyStatusMismatch` that caused the error.
45    #[error("{0}")]
46    PartyStatusMismatch(PartyStatusMismatch),
47
48    /// Occurs when there is an error during serialization.
49    ///
50    /// - `0`: The specific `SerializationError` encountered.
51    #[error("{0}")]
52    SerializationError(SerializationError),
53
54    /// Occurs when sending a message related to the event fails.
55    ///
56    /// - `0`: A string describing the reason for the failure.
57    #[error("{0}")]
58    FailedToSendMessage(String),
59}
60
61/// Represents the various errors that can occur when updating the state in a consensus protocol.
62///
63/// This enum is generic over `V`, which must implement the `Value` trait.
64#[derive(Error, Debug)]
65pub enum UpdateStateError<V: Value> {
66    /// Occurs when there is a mismatch in the expected party status.
67    ///
68    /// - `0`: The specific `PartyStatusMismatch` that caused the error.
69    #[error("{0}")]
70    PartyStatusMismatch(PartyStatusMismatch),
71
72    /// Occurs when there is a mismatch in the ballot number.
73    ///
74    /// - `0`: The specific `BallotNumberMismatch` that caused the error.
75    #[error("{0}")]
76    BallotNumberMismatch(BallotNumberMismatch),
77
78    /// Occurs when there is a mismatch in the expected leader.
79    ///
80    /// - `0`: The specific `LeaderMismatch` that caused the error.
81    #[error("{0}")]
82    LeaderMismatch(LeaderMismatch),
83
84    /// Occurs when there is a mismatch in the expected value.
85    ///
86    /// - `0`: The specific `ValueMismatch<V>` that caused the error, where `V` is the type of the value.
87    #[error("{0}")]
88    ValueMismatch(ValueMismatch<V>),
89
90    /// Occurs when the value verification fails during the state update process.
91    #[error("value verification failed")]
92    ValueVerificationFailed,
93
94    /// Occurs when there is an error during deserialization.
95    ///
96    /// - `0`: The specific `DeserializationError` encountered.
97    #[error("{0}")]
98    DeserializationError(DeserializationError),
99}
100
101/// Represents an error that occurs when there is a mismatch between the current status of the party
102/// and the status required for an operation.
103///
104/// This error is typically encountered when an operation requires the party to be in a specific
105/// state, but the party is in a different state.
106#[derive(Error, Debug)]
107#[error(
108    "party status mismatch: party status is {party_status} whilst needed status is {needed_status}"
109)]
110pub struct PartyStatusMismatch {
111    /// The current status of the party.
112    pub party_status: PartyStatus,
113    /// The status required for the operation to proceed.
114    pub needed_status: PartyStatus,
115}
116
117/// Represents an error that occurs when there is a mismatch between the ballot number of the party
118/// and the ballot number received in a message.
119#[derive(Error, Debug)]
120#[error("ballot number mismatch: party's ballot number is {party_ballot_number} whilst received {message_ballot_number} in the message")]
121pub struct BallotNumberMismatch {
122    /// The ballot number held by the party.
123    pub party_ballot_number: u64,
124    /// The ballot number received in the message.
125    pub message_ballot_number: u64,
126}
127
128/// Represents an error that occurs when there is a mismatch between the expected leader
129/// of the party and the sender of the message.
130#[derive(Error, Debug)]
131#[error("leader mismatch: party's leader is {party_leader} whilst the message was sent by {message_sender}")]
132pub struct LeaderMismatch {
133    /// The leader identifier of the party.
134    pub party_leader: u64,
135    /// The identifier of the message sender.
136    pub message_sender: u64,
137}
138
139/// Represents an error that occurs when there is a mismatch between the value held by the party
140/// and the value received in a message.
141///
142/// This struct is generic over `V`, which must implement the `Value` trait.
143#[derive(Error, Debug)]
144#[error(
145    "value mismatch: party's value is {party_value} whilst received {message_value} in the message"
146)]
147pub struct ValueMismatch<V: Value> {
148    /// The value held by the party.
149    pub party_value: V,
150    /// The value received in the message.
151    pub message_value: V,
152}
153
154/// Represents the various errors that can occur during the deserialization process.
155#[derive(Error, Debug)]
156pub enum DeserializationError {
157    /// Occurs when there is an error deserializing a message.
158    ///
159    /// - `0`: A string describing the specific deserialization error for the message.
160    #[error("message deserialization error: {0}")]
161    Message(String),
162
163    /// Occurs when there is an error deserializing a value.
164    ///
165    /// - `0`: A string describing the specific deserialization error for the value.
166    #[error("value deserialization error: {0}")]
167    Value(String),
168}
169
170/// Represents the various errors that can occur during the serialization process.
171#[derive(Error, Debug)]
172pub enum SerializationError {
173    /// Occurs when there is an error serializing a message.
174    ///
175    /// - `0`: A string describing the specific serialization error for the message.
176    #[error("message serialization error: {0}")]
177    Message(String),
178
179    /// Occurs when there is an error serializing a value.
180    ///
181    /// - `0`: A string describing the specific serialization error for the value.
182    #[error("value serialization error: {0}")]
183    Value(String),
184}
185
186/// Converts a `PartyStatusMismatch` into a `FollowEventError`.
187///
188/// This conversion allows `PartyStatusMismatch` errors to be treated as `FollowEventError`,
189/// which may occur when there is a status mismatch while following an event.
190impl From<PartyStatusMismatch> for FollowEventError {
191    fn from(error: PartyStatusMismatch) -> Self {
192        FollowEventError::PartyStatusMismatch(error)
193    }
194}
195
196/// Converts a `SerializationError` into a `FollowEventError`.
197///
198/// This conversion is used when a serialization error occurs during the process
199/// of following an event, allowing it to be handled as a `FollowEventError`.
200impl From<SerializationError> for FollowEventError {
201    fn from(error: SerializationError) -> Self {
202        FollowEventError::SerializationError(error)
203    }
204}
205
206/// Converts a `PartyStatusMismatch` into an `UpdateStateError<V>`.
207///
208/// This conversion is useful when a status mismatch occurs while updating the state,
209/// allowing the error to be handled within the context of state updates.
210impl<V: Value> From<PartyStatusMismatch> for UpdateStateError<V> {
211    fn from(error: PartyStatusMismatch) -> Self {
212        UpdateStateError::PartyStatusMismatch(error)
213    }
214}
215
216/// Converts a `LeaderMismatch` into an `UpdateStateError<V>`.
217///
218/// This conversion is used when there is a leader mismatch during state updates,
219/// allowing the error to be propagated and handled as an `UpdateStateError`.
220impl<V: Value> From<LeaderMismatch> for UpdateStateError<V> {
221    fn from(error: LeaderMismatch) -> Self {
222        UpdateStateError::LeaderMismatch(error)
223    }
224}
225
226/// Converts a `BallotNumberMismatch` into an `UpdateStateError<V>`.
227///
228/// This conversion is used when there is a ballot number mismatch during state updates,
229/// allowing the error to be propagated and handled as an `UpdateStateError`.
230impl<V: Value> From<BallotNumberMismatch> for UpdateStateError<V> {
231    fn from(error: BallotNumberMismatch) -> Self {
232        UpdateStateError::BallotNumberMismatch(error)
233    }
234}
235
236/// Converts a `ValueMismatch<V>` into an `UpdateStateError<V>`.
237///
238/// This conversion is used when there is a value mismatch during state updates,
239/// allowing the error to be propagated and handled as an `UpdateStateError`.
240impl<V: Value> From<ValueMismatch<V>> for UpdateStateError<V> {
241    fn from(error: ValueMismatch<V>) -> Self {
242        UpdateStateError::ValueMismatch(error)
243    }
244}
245
246/// Converts a `DeserializationError` into an `UpdateStateError<V>`.
247///
248/// This conversion is used when a deserialization error occurs during state updates,
249/// allowing the error to be handled within the context of state updates.
250impl<V: Value> From<DeserializationError> for UpdateStateError<V> {
251    fn from(error: DeserializationError) -> Self {
252        UpdateStateError::DeserializationError(error)
253    }
254}