use thiserror::Error;
#[derive(Debug, Error)]
pub enum WalError {
#[error("WAL schema mismatch: expected {expected}, found {found} (wipe the WAL directory)")]
SchemaMismatch { expected: u64, found: u64 },
#[error(
"WAL writer lock already held for {wal_path}{owner_suffix}",
owner_suffix = lock_owner_suffix(owner.as_deref())
)]
WalAlreadyLocked {
wal_path: String,
owner: Option<String>,
},
#[error("corrupt WAL record at app_seq={app_seq}: {details}")]
CorruptRecord { app_seq: u64, details: String },
#[error("WAL sequence gap during recovery: expected seq={expected}, found seq={found}")]
SequenceGap { expected: u64, found: u64 },
#[error(
"WAL recovery incomplete: need events through seq={required_through}, recovered through seq={recovered_through}"
)]
RecoveryIncomplete {
required_through: u64,
recovered_through: u64,
},
#[error(
"WAL cannot continue recovery after seq={after_seq}: tx_id={tx_id} does not complete (next expected seq={next_expected_seq})"
)]
IncompleteTxAfterCursor {
after_seq: u64,
tx_id: u64,
next_expected_seq: u64,
},
#[error(
"WAL recovery cursor seq={after_seq} is beyond the recoverable head seq={recoverable_head}"
)]
CursorBeyondRecoverableHead {
after_seq: u64,
recoverable_head: u64,
},
#[error("invalid tx framing at app_seq={app_seq}: tx_id={tx_id} tx_len={tx_len} tx_ix={tx_ix}")]
InvalidTxFraming {
app_seq: u64,
tx_id: u64,
tx_len: u16,
tx_ix: u16,
},
}
#[derive(Debug, Error)]
pub enum SegmentError {
#[error(
"segment contiguity gap: prev_end={prev_end_seq}, next_start={next_start_seq}, expected={expected}"
)]
ContiguityGap {
prev_end_seq: u64,
next_start_seq: u64,
expected: u64,
},
#[error("segment contiguity overlap: prev_end={prev_end_seq}, next_start={next_start_seq}")]
ContiguityOverlap {
prev_end_seq: u64,
next_start_seq: u64,
},
#[error("no segments found in {path}")]
NoSegments { path: String },
}
#[derive(Debug, Error)]
pub enum RuntimeError {
#[error("wal thread panicked")]
WalThreadPanic,
}
fn lock_owner_suffix(owner: Option<&str>) -> String {
match owner {
Some(owner) => format!(" (owner: {owner})"),
None => String::new(),
}
}