1use super::*;
5use coven_foundation::files::BootstrapDirectoryError;
6
7#[derive(Debug, thiserror::Error)]
12pub enum BootstrapError {
13 #[error("opening cancelled")]
15 Cancelled,
16 #[error("the join request may have been sent; the join stays unfinished")]
20 JoinRequestSent,
21 #[error("no join is under way for store {0}")]
24 NoUnfinishedJoin(StoreId),
25 #[error("the device may be registered; the restore stays unfinished")]
28 RestoreRegistered,
29 #[error("no restore is under way for store {0}")]
32 NoUnfinishedRestore(StoreId),
33 #[error("no replacement is under way for store {0}")]
36 NoUnfinishedReplacement(StoreId),
37 #[error(transparent)]
39 Code(#[from] CodeError),
40 #[error(transparent)]
42 Directory(BootstrapDirectoryError),
43 #[error(transparent)]
45 Store(CovenError),
46 #[error("{}: the device is locked, and the store's files are protected until it unlocks", path.display())]
52 DeviceLocked {
53 path: std::path::PathBuf,
55 },
56 #[error(transparent)]
58 Sync(SyncError),
59 #[error(transparent)]
61 OAuth(coven_storage::providers::OAuthError),
62 #[error(transparent)]
64 SecureStorage(KeyError),
65 #[error("{operation}; cleanup failed: {cleanup}")]
67 Cleanup {
68 operation: Box<BootstrapError>,
70 #[source]
72 cleanup: Box<BootstrapError>,
73 },
74 #[error("store is published; final durability or cleanup failed: {source}")]
77 Published {
78 handle: CovenHandle,
80 #[source]
82 source: Box<BootstrapError>,
83 },
84 #[error(transparent)]
87 Shutdown(#[from] crate::task::Shutdown),
88 #[error(transparent)]
90 Bug(#[from] crate::task::Bug),
91}
92
93impl From<BootstrapDirectoryError> for BootstrapError {
94 fn from(error: BootstrapDirectoryError) -> Self {
95 if let BootstrapDirectoryError::Bug(bug) = error {
96 return Self::Bug(bug);
97 }
98 match error.device_locked() {
99 Some(path) => Self::DeviceLocked { path: path.to_owned() },
100 None => Self::Directory(error),
101 }
102 }
103}
104
105impl From<SyncError> for BootstrapError {
108 fn from(error: SyncError) -> Self {
109 match error {
110 SyncError::Code(error) => Self::Code(error),
111 SyncError::Bug(bug) => Self::Bug(bug),
112 error => Self::Sync(error),
113 }
114 }
115}
116
117impl From<CovenError> for BootstrapError {
118 fn from(error: CovenError) -> Self {
119 match error {
120 CovenError::DeviceLocked { path } => Self::DeviceLocked { path },
121 CovenError::Bug(bug) => Self::Bug(bug),
122 error => Self::Store(error),
123 }
124 }
125}
126
127impl From<DbError> for BootstrapError {
129 fn from(error: DbError) -> Self {
130 CovenError::from(error).into()
131 }
132}
133
134impl From<coven_database::OpenError> for BootstrapError {
135 fn from(error: coven_database::OpenError) -> Self {
136 CovenError::from(error).into()
137 }
138}
139
140impl From<coven_storage::providers::OAuthError> for BootstrapError {
141 fn from(error: coven_storage::providers::OAuthError) -> Self {
142 match error {
143 coven_storage::providers::OAuthError::Storage(StorageError::Bug(bug)) => Self::Bug(bug),
144 error => Self::OAuth(error),
145 }
146 }
147}
148
149impl From<StoreLockError> for BootstrapError {
150 fn from(error: StoreLockError) -> Self {
151 BootstrapDirectoryError::from(error).into()
152 }
153}
154
155impl From<coven_foundation::files::FileError> for BootstrapError {
156 fn from(error: coven_foundation::files::FileError) -> Self {
157 BootstrapDirectoryError::from(error).into()
158 }
159}
160
161impl From<KeyError> for BootstrapError {
162 fn from(error: KeyError) -> Self {
163 match error {
164 KeyError::Bug(bug) => Self::Bug(bug),
165 error => Self::SecureStorage(error),
166 }
167 }
168}
169
170impl crate::task::CarriesBug for BootstrapError {
171 fn bug(&self) -> Option<&crate::task::Bug> {
172 match self {
173 Self::Bug(bug) => Some(bug),
174 Self::Directory(error) => error.bug(),
175 Self::Store(error) => error.bug(),
176 Self::Sync(error) => error.bug(),
177 Self::OAuth(error) => error.bug(),
178 Self::SecureStorage(error) => error.bug(),
179 Self::Cleanup { operation, cleanup } => operation.bug().or_else(|| cleanup.bug()),
180 Self::Published { source, .. } => source.bug(),
181 _ => None,
182 }
183 }
184}
185
186impl From<crate::task::TaskFailed> for BootstrapError {
187 fn from(failed: crate::task::TaskFailed) -> Self {
188 failed.into_error()
189 }
190}