Skip to main content

coven_replication/sync/cycle/
failure.rs

1#[derive(Debug)]
2pub struct SyncCycleFailure {
3    kind: SyncCycleFailureKind,
4    operation: &'static str,
5    cause: Box<SyncCycleCause>,
6}
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9enum SyncCycleFailureKind {
10    Offline,
11    Failed,
12}
13
14impl SyncCycleFailure {
15    pub(crate) fn operation<E>(operation: &'static str, error: E) -> Self
16    where
17        E: Into<SyncCycleCause>,
18    {
19        let cause = error.into();
20        let kind = if crate::sync::error::error_chain_contains_transport(&cause) {
21            SyncCycleFailureKind::Offline
22        } else {
23            SyncCycleFailureKind::Failed
24        };
25        Self {
26            kind,
27            operation,
28            cause: Box::new(cause),
29        }
30    }
31
32    pub(crate) fn is_offline(&self) -> bool {
33        self.kind == SyncCycleFailureKind::Offline
34    }
35
36    pub(super) fn concurrent(first: Self, second: Self) -> Self {
37        let kind = if first.is_offline() || second.is_offline() {
38            SyncCycleFailureKind::Offline
39        } else {
40            SyncCycleFailureKind::Failed
41        };
42        Self {
43            kind,
44            operation: "run Store publication and blob upload lanes",
45            cause: Box::new(SyncCycleCause::Concurrent {
46                first: Box::new(first),
47                second: Box::new(second),
48            }),
49        }
50    }
51
52    #[cfg(test)]
53    pub(crate) fn contains(&self, pattern: &str) -> bool {
54        self.to_string().contains(pattern)
55    }
56}
57
58impl std::fmt::Display for SyncCycleFailure {
59    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60        write!(formatter, "{}: {}", self.operation, self.cause)
61    }
62}
63
64impl std::error::Error for SyncCycleFailure {
65    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
66        Some(self.cause.as_ref())
67    }
68}
69
70#[derive(Debug, thiserror::Error)]
71pub(crate) enum SyncCycleCause {
72    #[error("{first}; concurrently, {second}")]
73    Concurrent {
74        first: Box<SyncCycleFailure>,
75        second: Box<SyncCycleFailure>,
76    },
77    #[error("{0}")]
78    Database(#[from] coven_database::DbError),
79    #[error("{0}")]
80    Store(#[from] crate::sync::store::StoreError),
81    #[error("{0}")]
82    Registration(#[from] crate::sync::store::StoreRegistrationError),
83    #[error("{0}")]
84    Initialization(#[from] crate::sync::store::StoreInitializationError),
85    #[error("{0}")]
86    Circle(#[from] crate::sync::store::CircleOperationError),
87    #[error("{0}")]
88    DeviceExclusion(#[from] crate::sync::store::StoreDeviceExclusionError),
89    #[error("{0}")]
90    Reclaim(#[from] crate::sync::store::StoreReclaimError),
91    #[error("{0}")]
92    DeviceJoin(#[from] crate::sync::store::DeviceJoinError),
93    #[error("{0}")]
94    TombstoneDrain(#[from] crate::blob::delete::TombstoneDrainError),
95    #[error("{0}")]
96    TombstoneGc(#[from] crate::sync::store::commit_publication::operation::TombstoneGcError),
97    #[error("{0}")]
98    UploadFailures(#[from] crate::blob::UploadFailures),
99    #[error("{0}")]
100    WriterAuthorization(
101        #[from] crate::sync::store::commit_publication::operation::StoreWriterAuthorizationError,
102    ),
103    #[error("{0}")]
104    Acknowledgement(#[from] crate::sync::store::acknowledgements::StoreAckError),
105    #[error("{0}")]
106    Membership(#[from] crate::sync::store::MembershipOpsError),
107    #[error("{0}")]
108    Pull(#[from] crate::sync::store::StorePullError),
109    #[error("{0}")]
110    AuthorizationRefresh(
111        #[from] crate::sync::store::commit_publication::operation::AuthorizationRefreshError,
112    ),
113    #[error("{0}")]
114    PublishedBlobDrop(#[from] crate::sync::store::blob::PublishedBlobDropError),
115    #[error("{0}")]
116    StoreProtocol(#[from] coven_protocol::store_commit::StoreProtocolError),
117    #[error("{0}")]
118    RowRoutingKey(#[from] coven_protocol::circle::RowRoutingKeyError),
119    #[error("{0}")]
120    Snapshot(#[from] crate::sync::store::snapshots::SnapshotError),
121}
122
123#[cfg(test)]
124#[path = "failure_tests.rs"]
125mod tests;