Skip to main content

coven_replication/sync/store/device_join/
error.rs

1#[derive(Debug, thiserror::Error)]
2pub enum DeviceJoinError {
3    #[error("device join signature is invalid")]
4    InvalidSignature,
5    #[error("device join offer does not name one active Store/member/provider authority")]
6    OfferMismatch,
7    #[error(
8        "device provider admission approval differs from its request or activated access grant"
9    )]
10    ApprovalMismatch,
11    #[error("device registration request differs from its offer, approval, or reserved slots")]
12    RegistrationRequestMismatch,
13    #[error("device join attempt differs from its signed exchange")]
14    AttemptMismatch,
15    #[error("device join cleanup does not contain the unconditional canonical slot set")]
16    CleanupMismatch,
17    #[error("device join journal transition is not the declared adjacent transition")]
18    NonAdjacentJournalTransition,
19    #[error("device join journal has a different durable value for this role and attempt")]
20    JournalConflict,
21    #[error("device join reserved slots are not pairwise distinct")]
22    DuplicateReservedSlot,
23    #[error("device join requires an existing Member identity")]
24    MemberNotEligible,
25    #[error("provider operation failed: {0}")]
26    Provider(String),
27    #[error("provider storage failed: {0}")]
28    ProviderStorage(#[source] coven_protocol::objects::StorageError),
29    #[error("provider capability proof failed: {0}")]
30    ProviderProbe(#[source] coven_protocol::provider::ProviderProbeError),
31    #[error("Store device join state: {0}")]
32    Store(String),
33    #[error("device join readiness task failed: {0}")]
34    JoinTask(#[from] tokio::task::JoinError),
35    #[error("Store device join writer authorization: {0}")]
36    WriterAuthorization(#[source] Box<crate::sync::store::StoreWriterAuthorizationError>),
37    #[error("Store device join membership chain: {0}")]
38    MembershipChain(#[source] Box<crate::sync::store::AnchoredChainError>),
39    #[error("Store device join database state: {0}")]
40    Database(#[from] coven_database::DbError),
41    #[error("device join requires an activated local Store device")]
42    ActiveDeviceRequired,
43    #[error("device join requires the active local Owner authority")]
44    OwnerAuthorityRequired,
45    #[error("device join requires the selected effective provider administrator")]
46    ProviderAdministratorRequired,
47    #[error("device join requires resolved Store membership")]
48    MembershipConflict,
49    #[error("device join attempt cut does not include its provider-access activation")]
50    ApprovalActivationMissing,
51    #[error("device join activation is not materialized in the installed Store database")]
52    ActivationNotMaterialized,
53    #[error(transparent)]
54    Object(#[from] coven_protocol::objects::StoreObjectError),
55    #[error(transparent)]
56    Registration(#[from] crate::sync::store::StoreRegistrationError),
57    #[error(transparent)]
58    Pull(#[from] crate::sync::store::pull::StorePullError),
59    #[error(transparent)]
60    Outbound(#[from] crate::sync::store::StoreError),
61    #[error(transparent)]
62    Protocol(#[from] coven_protocol::store_commit::StoreProtocolError),
63    #[error(transparent)]
64    Storage(#[from] coven_protocol::objects::StorageError),
65    #[error(transparent)]
66    Serialization(#[from] serde_json::Error),
67}
68
69impl From<crate::sync::store::StoreWriterAuthorizationError> for DeviceJoinError {
70    fn from(error: crate::sync::store::StoreWriterAuthorizationError) -> Self {
71        Self::WriterAuthorization(Box::new(error))
72    }
73}
74
75impl From<crate::sync::store::AnchoredChainError> for DeviceJoinError {
76    fn from(error: crate::sync::store::AnchoredChainError) -> Self {
77        Self::MembershipChain(Box::new(error))
78    }
79}
80
81impl DeviceJoinError {
82    /// A retained prepared object that opens to different bytes is the caller's
83    /// `mismatch` verdict; every other failure is the storage failure itself.
84    pub(crate) fn prepared_object(
85        error: coven_protocol::objects::StorageError,
86        mismatch: Self,
87    ) -> Self {
88        match error {
89            coven_protocol::objects::StorageError::PreparedObjectMismatch(_) => mismatch,
90            error => Self::Storage(error),
91        }
92    }
93}
94
95impl From<coven_protocol::store_commit::device_join_exchange::DeviceJoinExchangeError>
96    for DeviceJoinError
97{
98    fn from(
99        error: coven_protocol::store_commit::device_join_exchange::DeviceJoinExchangeError,
100    ) -> Self {
101        use coven_protocol::store_commit::device_join_exchange::DeviceJoinExchangeError as E;
102        match error {
103            E::InvalidSignature => DeviceJoinError::InvalidSignature,
104            E::OfferMismatch => DeviceJoinError::OfferMismatch,
105            E::ApprovalMismatch => DeviceJoinError::ApprovalMismatch,
106            E::RegistrationRequestMismatch => DeviceJoinError::RegistrationRequestMismatch,
107            E::AttemptMismatch => DeviceJoinError::AttemptMismatch,
108            E::CleanupMismatch => DeviceJoinError::CleanupMismatch,
109            E::DuplicateReservedSlot => DeviceJoinError::DuplicateReservedSlot,
110            E::Provider(error) => DeviceJoinError::ProviderProbe(error),
111            E::Storage(error) => DeviceJoinError::Storage(error),
112            E::Protocol(error) => DeviceJoinError::Protocol(error),
113        }
114    }
115}
116
117impl From<coven_database::DeviceJoinJournalError> for DeviceJoinError {
118    fn from(error: coven_database::DeviceJoinJournalError) -> Self {
119        use coven_database::DeviceJoinJournalError as E;
120        match error {
121            E::NonAdjacentJournalTransition => DeviceJoinError::NonAdjacentJournalTransition,
122            E::JournalConflict => DeviceJoinError::JournalConflict,
123            E::Serialization(error) => DeviceJoinError::Serialization(error),
124            E::Database(error) => DeviceJoinError::Database(error),
125        }
126    }
127}