pathfinder_consensus/error.rs
1//! Error types for the consensus engine.
2
3use std::fmt;
4
5/// An error that occurred in the consensus engine.
6///
7/// This error type wraps internal errors and provides information about
8/// whether the error is recoverable or fatal.
9#[derive(Debug)]
10pub struct ConsensusError {
11 inner: anyhow::Error,
12 kind: ErrorKind,
13}
14
15// Note: We don't expose malachite error types in the public API.
16// The error is converted to anyhow::Error internally.
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19pub enum ErrorKind {
20 /// Error occurred during WAL recovery (e.g., corrupted entry)
21 WalRecovery,
22 /// Error from the consensus engine internals (e.g., malachite errors)
23 Internal,
24}
25
26impl ConsensusError {
27 /// Create a WAL recovery error (recoverable).
28 pub fn wal_recovery(error: anyhow::Error) -> Self {
29 Self {
30 inner: error,
31 kind: ErrorKind::WalRecovery,
32 }
33 }
34
35 /// Create an internal consensus engine error from a malachite error.
36 ///
37 /// All malachite errors are treated as fatal and classified as internal
38 /// errors, but we could potentially identify recoverable ones in the
39 /// future.
40 pub(crate) fn malachite<Ctx>(error: malachite_consensus::Error<Ctx>) -> Self
41 where
42 Ctx: malachite_types::Context,
43 {
44 // Convert to anyhow::Error for storage (we don't leak malachite types)
45 let anyhow_err: anyhow::Error = error.into();
46
47 Self {
48 inner: anyhow_err,
49 kind: ErrorKind::Internal,
50 }
51 }
52
53 /// Check if this error is recoverable.
54 ///
55 /// Recoverable errors are those that don't indicate state corruption or
56 /// bugs, and the consensus engine can continue operating after handling
57 /// them.
58 pub fn is_recoverable(&self) -> bool {
59 matches!(self.kind, ErrorKind::WalRecovery)
60 }
61}
62
63impl fmt::Display for ConsensusError {
64 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65 write!(f, "{}", self.inner)
66 }
67}
68
69impl std::error::Error for ConsensusError {
70 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
71 self.inner.source()
72 }
73}