coven_database/write_failure.rs
1//! Preserve the facade's callback failure when a transaction or cleanup also fails.
2//! A committed result never becomes a failure because of cleanup (ยง2.1, Appendix C.3).
3
4use crate::DbError;
5
6/// A caller's write error can retain both its original cause and failures that
7/// happen while rolling back or removing bytes, and says which bug it carries,
8/// for a write whose caller stopped waiting (E15). A write fails with its
9/// closure's own error type, which implements this: `DbError` for ordinary
10/// database clients, sync's error for sync's writes, and an app's own type
11/// for the app's writes through the facade (E3).
12pub trait WriteFailure:
13 From<DbError> + From<rusqlite::Error> + coven_foundation::task::CarriesBug
14{
15 /// Retain a failed rollback alongside the original failure.
16 fn with_rollback(self, rollback: rusqlite::Error) -> Self;
17 /// Retain the failed write's error and every failed byte-removal operation.
18 fn with_cleanup(write: Self, failures: Vec<DbError>) -> Self
19 where
20 Self: Sized;
21}
22
23/// The outcome of an operation whose released bytes were then removed. A
24/// failed removal stays recorded for the next write or open (Appendix C.3): it
25/// joins a failed operation's error, and leaves a committed result as it is.
26pub(crate) fn after_cleanup<R, E: WriteFailure>(
27 result: Result<R, E>,
28 failures: Vec<DbError>,
29) -> Result<R, E> {
30 if failures.is_empty() {
31 return result;
32 }
33 match result {
34 Ok(result) => {
35 tracing::error!(
36 ?failures,
37 "removing released file bytes failed; their records stay for the next write or open"
38 );
39 Ok(result)
40 }
41 Err(error) => Err(E::with_cleanup(error, failures)),
42 }
43}
44
45impl WriteFailure for DbError {
46 fn with_rollback(self, rollback: rusqlite::Error) -> Self {
47 Self::Rollback { operation: Box::new(self), rollback }
48 }
49 fn with_cleanup(write: Self, failures: Vec<DbError>) -> Self {
50 Self::FileCleanup { write: Err(Box::new(write)), failures }
51 }
52}