1use serde::{de::DeserializeOwned, Deserialize, Serialize};
2
3use crate::types::{identifiers::FaultyPeer, PeerId, PeerIndex};
4
5mod builder_error;
6
7pub use builder_error::BuilderError;
8
9pub trait Error:
11 std::error::Error + Clone + PartialEq + Eq + Serialize + DeserializeOwned + Send + Sync
12{
13}
14impl<T> Error for T where
15 T: std::error::Error + Clone + PartialEq + Eq + Serialize + DeserializeOwned + Send + Sync
16{
17}
18
19#[derive(thiserror::Error, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
20#[repr(C)]
21pub enum PrimitiveError {
22 #[error("Serialization Failed: {0}.")]
24 SerializationFailed(String),
25 #[error("Deserialization Failed: {0}.")]
26 DeserializationFailed(String),
27
28 #[error("Wrong Opening: Expected {0}, got {1}.")]
30 WrongOpening(String, String),
31 #[error("Wrong Opening for {0}: Expected {1}, got {2}.")]
32 WrongOpeningFor(FaultyPeer, String, String),
33 #[error("Wrong Echo from {0}.")]
34 WrongEcho(FaultyPeer),
35 #[error("Wrong signature: {0}.")]
36 WrongSignature(String),
37 #[error("Wrong MAC for {0}: got {1:?}.")]
38 WrongMACFor(FaultyPeer, String),
39 #[error("Wrong MAC: got {0:?}.")]
40 WrongMAC(String),
41 #[error("Wrong correlation. {0}")]
42 WrongCorrelation(String),
43
44 #[error("Invalid Size: expected {0} elements, got {1}")]
46 InvalidSize(usize, usize),
47 #[error("Minimum Length Error: expected at least {0} elements, got {1}")]
48 MinimumLength(usize, usize),
49 #[error("Invalid Parameters: {0}")]
50 InvalidParameters(String),
51 #[error("PeerIndex out of bounds: {0} ∉ [0, {1}].")]
52 InvalidPeerIndex(PeerIndex, usize),
53 #[error("Invalid peer ID: {0}")]
54 InvalidPeerId(PeerId),
55
56 #[error("Zero value sampled for type {0}")]
58 ZeroValueSampled(String),
59}
60
61impl From<quinn::rustls::Error> for PrimitiveError {
62 fn from(err: quinn::rustls::Error) -> Self {
63 PrimitiveError::InvalidParameters(err.to_string())
64 }
65}
66
67impl From<Vec<PrimitiveError>> for PrimitiveError {
68 fn from(errors: Vec<PrimitiveError>) -> Self {
71 if errors.is_empty() {
72 return PrimitiveError::InvalidParameters(
73 "Cannot aggregate an empty list of errors.".to_owned(),
74 );
75 };
76 if errors.len() == 1 {
77 return errors.into_iter().next().unwrap();
78 }
79
80 let (peers, receiver, invalid_errs) = errors.into_iter().fold(
81 (vec![], vec![], vec![]),
82 |(mut peers, mut receiver, mut invalid_errors), e| {
83 match e {
84 PrimitiveError::WrongMACFor(p, r) => {
85 peers.push(p);
86 receiver.push(r);
87 }
88 PrimitiveError::WrongEcho(p) => {
89 peers.push(p);
90 }
91 _ => invalid_errors.push(e.to_string()),
92 }
93 (peers, receiver, invalid_errors)
94 },
95 );
96 if !invalid_errs.is_empty() {
97 return PrimitiveError::InvalidParameters(
98 "Only WrongMACFor|WrongEcho can be aggregated. Got: ".to_owned()
99 + &invalid_errs.join(", "),
100 );
101 }
102 match (peers, receiver.as_slice()) {
103 (peers, []) => PrimitiveError::WrongEcho(FaultyPeer::Multiple(peers)),
104 (peers, receiver) if peers.len() == receiver.len() => {
105 PrimitiveError::WrongMACFor(FaultyPeer::Multiple(peers), receiver.join(", "))
106 }
107 _ => PrimitiveError::InvalidParameters(
108 "All errors must be of the same type to be aggregated".to_owned(),
109 ),
110 }
111 }
112}
113impl PrimitiveError {
114 pub fn blame(self, peer_to_blame: PeerIndex) -> PrimitiveError {
116 match self {
117 PrimitiveError::WrongMAC(receiver) => {
118 PrimitiveError::WrongMACFor(FaultyPeer::Foreign(peer_to_blame), receiver)
119 }
120 PrimitiveError::WrongMACFor(peers, receiver) => {
121 PrimitiveError::WrongMACFor(peers.push(peer_to_blame), receiver)
122 }
123 PrimitiveError::WrongOpening(expected, got) => {
124 PrimitiveError::WrongOpeningFor(FaultyPeer::Foreign(peer_to_blame), expected, got)
125 }
126 PrimitiveError::WrongOpeningFor(peers, expected, got) => {
127 PrimitiveError::WrongOpeningFor(peers.push(peer_to_blame), expected, got)
128 }
129 _ => self,
130 }
131 }
132}