pub struct FailureReport { /* private fields */ }Expand description
A bounded structured report describing one transaction failure.
Implementations§
Source§impl FailureReport
impl FailureReport
Sourcepub fn phase(&self) -> FailurePhase
pub fn phase(&self) -> FailurePhase
Returns the phase that produced the failure.
Examples found in repository?
examples/receipts.rs (line 90)
61fn main() -> Result<(), Box<dyn std::error::Error>> {
62 // 1. Committed: success.
63 let (base, plan) = build(b"new", Some(b"old"))?;
64 let receipt = plan
65 .prepare()?
66 .verify_integrity()?
67 .validate(&AllValidators::new())?
68 .commit(CommitOwnership::new(
69 &ExistingAsOwnedVerifier,
70 AbsentPolicy::AllowCreate,
71 ))?;
72 assert_eq!(receipt.disposition(), TransactionDisposition::Committed);
73 assert!(receipt.failure().is_none());
74 println!("committed: {:?}", receipt.disposition());
75 let _ = fs::remove_dir_all(&base);
76
77 // 2. RolledBack: ownership denied, live state unchanged, failure explains why.
78 let (base, plan) = build(b"new", Some(b"old"))?;
79 let root = base.join("install");
80 let receipt = plan
81 .prepare()?
82 .verify_integrity()?
83 .validate(&AllValidators::new())?
84 .commit(CommitOwnership::new(&DenyAll, AbsentPolicy::AllowCreate))?;
85 assert_eq!(receipt.disposition(), TransactionDisposition::RolledBack);
86 assert!(receipt.rollback_verified());
87 let failure = receipt.failure().expect("rolled back carries a cause");
88 println!(
89 "rolled back: phase={} category={} detail={}",
90 failure.phase().as_str(),
91 failure.category().as_str(),
92 failure.detail()
93 );
94 assert_eq!(fs::read(root.join("bin/app"))?, b"old");
95 assert_ne!(
96 receipt.disposition(),
97 TransactionDisposition::Committed,
98 "rollback is not success"
99 );
100 let _ = fs::remove_dir_all(&base);
101
102 // 3. RecoveryRequired is distinct and high severity: it means Eggup cannot
103 // prove either generation is coherent. It is produced by rollback failure
104 // or unclean finalization; operators must inspect `recovery_path` and the
105 // preserved lock. See `docs/transaction.md` for the full contract.
106 println!("recovery-required: inspect recovery_path + lock; do not retry blindly");
107
108 // 4. A failed post-commit check can keep the coherent new generation,
109 // while remaining machine-readable as a failed check.
110 let (base, plan) = build(b"new", Some(b"old"))?;
111 let receipt = plan
112 .prepare()?
113 .verify_integrity()?
114 .validate(&AllValidators::new())?
115 .commit_with_post_commit(
116 CommitOwnership::new(&ExistingAsOwnedVerifier, AbsentPolicy::AllowCreate),
117 PostCommitFailurePolicy::KeepInstalled,
118 || Err("example health check failed"),
119 )?;
120 assert_eq!(receipt.disposition(), TransactionDisposition::Committed);
121 assert!(receipt.post_commit_failure().is_some());
122 println!(
123 "kept installed after failed check: {:?}",
124 receipt.disposition()
125 );
126 let _ = fs::remove_dir_all(base);
127 Ok(())
128}Sourcepub fn member(&self) -> Option<&MemberId>
pub fn member(&self) -> Option<&MemberId>
Returns the affected member, when the failure is member-specific.
Sourcepub fn category(&self) -> FailureCategory
pub fn category(&self) -> FailureCategory
Returns the stable failure category.
Examples found in repository?
examples/receipts.rs (line 91)
61fn main() -> Result<(), Box<dyn std::error::Error>> {
62 // 1. Committed: success.
63 let (base, plan) = build(b"new", Some(b"old"))?;
64 let receipt = plan
65 .prepare()?
66 .verify_integrity()?
67 .validate(&AllValidators::new())?
68 .commit(CommitOwnership::new(
69 &ExistingAsOwnedVerifier,
70 AbsentPolicy::AllowCreate,
71 ))?;
72 assert_eq!(receipt.disposition(), TransactionDisposition::Committed);
73 assert!(receipt.failure().is_none());
74 println!("committed: {:?}", receipt.disposition());
75 let _ = fs::remove_dir_all(&base);
76
77 // 2. RolledBack: ownership denied, live state unchanged, failure explains why.
78 let (base, plan) = build(b"new", Some(b"old"))?;
79 let root = base.join("install");
80 let receipt = plan
81 .prepare()?
82 .verify_integrity()?
83 .validate(&AllValidators::new())?
84 .commit(CommitOwnership::new(&DenyAll, AbsentPolicy::AllowCreate))?;
85 assert_eq!(receipt.disposition(), TransactionDisposition::RolledBack);
86 assert!(receipt.rollback_verified());
87 let failure = receipt.failure().expect("rolled back carries a cause");
88 println!(
89 "rolled back: phase={} category={} detail={}",
90 failure.phase().as_str(),
91 failure.category().as_str(),
92 failure.detail()
93 );
94 assert_eq!(fs::read(root.join("bin/app"))?, b"old");
95 assert_ne!(
96 receipt.disposition(),
97 TransactionDisposition::Committed,
98 "rollback is not success"
99 );
100 let _ = fs::remove_dir_all(&base);
101
102 // 3. RecoveryRequired is distinct and high severity: it means Eggup cannot
103 // prove either generation is coherent. It is produced by rollback failure
104 // or unclean finalization; operators must inspect `recovery_path` and the
105 // preserved lock. See `docs/transaction.md` for the full contract.
106 println!("recovery-required: inspect recovery_path + lock; do not retry blindly");
107
108 // 4. A failed post-commit check can keep the coherent new generation,
109 // while remaining machine-readable as a failed check.
110 let (base, plan) = build(b"new", Some(b"old"))?;
111 let receipt = plan
112 .prepare()?
113 .verify_integrity()?
114 .validate(&AllValidators::new())?
115 .commit_with_post_commit(
116 CommitOwnership::new(&ExistingAsOwnedVerifier, AbsentPolicy::AllowCreate),
117 PostCommitFailurePolicy::KeepInstalled,
118 || Err("example health check failed"),
119 )?;
120 assert_eq!(receipt.disposition(), TransactionDisposition::Committed);
121 assert!(receipt.post_commit_failure().is_some());
122 println!(
123 "kept installed after failed check: {:?}",
124 receipt.disposition()
125 );
126 let _ = fs::remove_dir_all(base);
127 Ok(())
128}Sourcepub fn detail(&self) -> &str
pub fn detail(&self) -> &str
Returns bounded human-readable detail.
Examples found in repository?
examples/receipts.rs (line 92)
61fn main() -> Result<(), Box<dyn std::error::Error>> {
62 // 1. Committed: success.
63 let (base, plan) = build(b"new", Some(b"old"))?;
64 let receipt = plan
65 .prepare()?
66 .verify_integrity()?
67 .validate(&AllValidators::new())?
68 .commit(CommitOwnership::new(
69 &ExistingAsOwnedVerifier,
70 AbsentPolicy::AllowCreate,
71 ))?;
72 assert_eq!(receipt.disposition(), TransactionDisposition::Committed);
73 assert!(receipt.failure().is_none());
74 println!("committed: {:?}", receipt.disposition());
75 let _ = fs::remove_dir_all(&base);
76
77 // 2. RolledBack: ownership denied, live state unchanged, failure explains why.
78 let (base, plan) = build(b"new", Some(b"old"))?;
79 let root = base.join("install");
80 let receipt = plan
81 .prepare()?
82 .verify_integrity()?
83 .validate(&AllValidators::new())?
84 .commit(CommitOwnership::new(&DenyAll, AbsentPolicy::AllowCreate))?;
85 assert_eq!(receipt.disposition(), TransactionDisposition::RolledBack);
86 assert!(receipt.rollback_verified());
87 let failure = receipt.failure().expect("rolled back carries a cause");
88 println!(
89 "rolled back: phase={} category={} detail={}",
90 failure.phase().as_str(),
91 failure.category().as_str(),
92 failure.detail()
93 );
94 assert_eq!(fs::read(root.join("bin/app"))?, b"old");
95 assert_ne!(
96 receipt.disposition(),
97 TransactionDisposition::Committed,
98 "rollback is not success"
99 );
100 let _ = fs::remove_dir_all(&base);
101
102 // 3. RecoveryRequired is distinct and high severity: it means Eggup cannot
103 // prove either generation is coherent. It is produced by rollback failure
104 // or unclean finalization; operators must inspect `recovery_path` and the
105 // preserved lock. See `docs/transaction.md` for the full contract.
106 println!("recovery-required: inspect recovery_path + lock; do not retry blindly");
107
108 // 4. A failed post-commit check can keep the coherent new generation,
109 // while remaining machine-readable as a failed check.
110 let (base, plan) = build(b"new", Some(b"old"))?;
111 let receipt = plan
112 .prepare()?
113 .verify_integrity()?
114 .validate(&AllValidators::new())?
115 .commit_with_post_commit(
116 CommitOwnership::new(&ExistingAsOwnedVerifier, AbsentPolicy::AllowCreate),
117 PostCommitFailurePolicy::KeepInstalled,
118 || Err("example health check failed"),
119 )?;
120 assert_eq!(receipt.disposition(), TransactionDisposition::Committed);
121 assert!(receipt.post_commit_failure().is_some());
122 println!(
123 "kept installed after failed check: {:?}",
124 receipt.disposition()
125 );
126 let _ = fs::remove_dir_all(base);
127 Ok(())
128}Trait Implementations§
Source§impl Clone for FailureReport
impl Clone for FailureReport
Source§impl Debug for FailureReport
impl Debug for FailureReport
impl Eq for FailureReport
Source§impl PartialEq for FailureReport
impl PartialEq for FailureReport
impl StructuralPartialEq for FailureReport
Auto Trait Implementations§
impl Freeze for FailureReport
impl RefUnwindSafe for FailureReport
impl Send for FailureReport
impl Sync for FailureReport
impl Unpin for FailureReport
impl UnsafeUnpin for FailureReport
impl UnwindSafe for FailureReport
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more