grafos_pipeline/
error.rs

1extern crate alloc;
2use alloc::string::String;
3use core::fmt;
4
5use grafos_fence::FenceEpoch;
6
7/// Errors that can occur during edge operations.
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub enum EdgeError {
10    /// The queue is full and cannot accept more items.
11    QueueFull,
12    /// The queue is empty.
13    QueueEmpty,
14    /// The underlying connection or queue has been disconnected.
15    Disconnected,
16    /// The lease backing this queue has expired.
17    LeaseExpired,
18    /// The edge generation is behind the expected generation.
19    StaleGeneration {
20        expected: FenceEpoch,
21        got: FenceEpoch,
22    },
23    /// Relocation of the edge to a new queue failed.
24    RelocateFailed(String),
25    /// Writing or reading a checkpoint failed.
26    CheckpointFailed(String),
27}
28
29impl fmt::Display for EdgeError {
30    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31        match self {
32            EdgeError::QueueFull => write!(f, "queue full"),
33            EdgeError::QueueEmpty => write!(f, "queue empty"),
34            EdgeError::Disconnected => write!(f, "disconnected"),
35            EdgeError::LeaseExpired => write!(f, "lease expired"),
36            EdgeError::StaleGeneration { expected, got } => {
37                write!(f, "stale generation: expected {expected}, got {got}")
38            }
39            EdgeError::RelocateFailed(msg) => write!(f, "relocate failed: {msg}"),
40            EdgeError::CheckpointFailed(msg) => write!(f, "checkpoint failed: {msg}"),
41        }
42    }
43}
44
45#[cfg(feature = "std")]
46impl std::error::Error for EdgeError {}
47
48impl From<grafos_std::error::FabricError> for EdgeError {
49    fn from(e: grafos_std::error::FabricError) -> Self {
50        match e {
51            grafos_std::error::FabricError::LeaseExpired => EdgeError::LeaseExpired,
52            grafos_std::error::FabricError::Disconnected => EdgeError::Disconnected,
53            grafos_std::error::FabricError::Fenced => EdgeError::Disconnected,
54            other => EdgeError::RelocateFailed(alloc::format!("{other}")),
55        }
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use super::*;
62
63    #[test]
64    fn display_variants() {
65        assert_eq!(format!("{}", EdgeError::QueueFull), "queue full");
66        assert_eq!(format!("{}", EdgeError::QueueEmpty), "queue empty");
67        assert_eq!(format!("{}", EdgeError::Disconnected), "disconnected");
68        assert_eq!(format!("{}", EdgeError::LeaseExpired), "lease expired");
69        assert_eq!(
70            format!(
71                "{}",
72                EdgeError::StaleGeneration {
73                    expected: FenceEpoch::new(2),
74                    got: FenceEpoch::new(1),
75                }
76            ),
77            "stale generation: expected epoch(2), got epoch(1)"
78        );
79        assert_eq!(
80            format!("{}", EdgeError::RelocateFailed("oops".into())),
81            "relocate failed: oops"
82        );
83        assert_eq!(
84            format!("{}", EdgeError::CheckpointFailed("bad".into())),
85            "checkpoint failed: bad"
86        );
87    }
88
89    #[test]
90    fn from_fabric_error() {
91        let e: EdgeError = grafos_std::error::FabricError::LeaseExpired.into();
92        assert_eq!(e, EdgeError::LeaseExpired);
93
94        let e: EdgeError = grafos_std::error::FabricError::Disconnected.into();
95        assert_eq!(e, EdgeError::Disconnected);
96
97        let e: EdgeError = grafos_std::error::FabricError::Fenced.into();
98        assert_eq!(e, EdgeError::Disconnected);
99    }
100}