Skip to main content

git_policy_cli/
recovery_error.rs

1//! What:
2//!  The fail-closed failure of reading or recovering durable transaction state.
3//! Why:
4//!  Malformed,
5//!  unsafe or contradictory state is never guessed at or deleted:
6//!  the command
7//!      stops with exit status 2 and a message naming the path,
8//!  and the state stays for
9//!      inspection (`CommitTransactionRecoveryError` in the incumbent;
10//!  implementation plan,
11//!      "Commit transactions and recovery").
12//!
13//! In TS you'd write (pseudocode):
14//! ```ts
15//! throw new CommitTransactionRecoveryError(`Unsafe transaction registry: ${root}`);
16//! ```
17
18/// What:
19///  One recovery failure with its complete,
20///  human-readable message.
21///       A tuple-like `struct` holds one unnamed field.
22/// Why:
23///   Every site that fails closed knows what it found and where;
24///  the message is the
25///       whole diagnostic.
26///
27/// In TS you'd write (pseudocode):
28/// ```ts
29/// class CommitTransactionRecoveryError extends Error {}
30/// ```
31#[derive(Clone, Debug, Eq, PartialEq)]
32pub struct RecoveryError(pub String);
33
34/// What:
35///  The message as display text.
36/// Why:
37///   Diagnostics print the message unchanged.
38///
39/// In TS you'd write (pseudocode):
40/// ```ts
41/// error.message
42/// ```
43impl std::fmt::Display for RecoveryError {
44    /// Writes the message.
45    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46        return formatter.write_str(self.0.as_str());
47    }
48}
49
50/// What:
51///  A recovery failure for a filesystem step that failed.
52/// Why:
53///   One constructor names the step,
54///  the path and the operating system's reason the same
55///       way everywhere.
56///
57/// In TS you'd write (pseudocode):
58/// ```ts
59/// new CommitTransactionRecoveryError(`${operation} ${path} failed: ${error.message}`)
60/// ```
61pub fn io_failure(
62    operation: &str,
63    path: &std::path::Path,
64    error: &std::io::Error,
65) -> RecoveryError {
66    return RecoveryError(format!("{operation} {} failed: {error}", path.display()));
67}
68
69/// Message controls stay out of the release executable.
70#[cfg(test)]
71#[path = "recovery_error_tests.rs"]
72mod tests;