use liminal::durability::DurabilityError;
use super::facts::FactsError;
use super::routed_stream::{RoutedStreamError, RoutedStreamRefusal};
#[derive(Clone, Copy, Debug, PartialEq, Eq, thiserror::Error)]
pub(super) enum RegistryRowRefusal {
#[error("a retire of an id that is not live")]
RetireNotLive,
#[error("a swept of an id that is not sweeping")]
SweptNotSweeping,
#[error("a registration of an id that is sweeping")]
RegisterSweeping,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, thiserror::Error)]
pub(super) enum FencedAttachProofRefusal {
#[error("Ordinary mode carries a request marker")]
OrdinaryRequestMarker,
#[error("Superseding mode carries a request marker")]
SupersedingRequestMarker,
#[error("Superseding terminal order differs from the Attached order")]
SupersedingTerminalOrder,
#[error("request marker differs from the fenced mode marker")]
RequestMarkerMismatch,
#[error("DetachedCredentialRecovery bytes are malformed")]
DetachedCredentialRecoveryMalformed,
#[error("DetachedCredentialRecovery bytes are not canonical")]
DetachedCredentialRecoveryNonCanonical,
#[error("predecessor debt bytes are malformed")]
PredecessorDebtMalformed,
#[error("predecessor debt bytes are not canonical")]
PredecessorDebtNonCanonical,
#[error("predecessor debt is zero")]
PredecessorDebtZero,
#[error("restricted successor bytes are malformed")]
SuccessorMalformed,
#[error("restricted successor bytes are not canonical")]
SuccessorNonCanonical,
#[error("restricted successor debt is zero")]
SuccessorDebtZero,
#[error("physical-compaction successor range is inverted")]
SuccessorCompactionRange,
#[error("recovery conversation differs from the Attached request")]
RecoveryConversationMismatch,
#[error("recovery participant differs from the Attached request")]
RecoveryParticipantMismatch,
#[error("recovery marker differs from the fenced mode")]
RecoveryMarkerMismatch,
#[error("recovery prior epoch differs from the fenced mode")]
RecoveryPriorEpochMismatch,
#[error("new binding generation is not immediately after the prior epoch")]
NewBindingGenerationMismatch,
#[error("cursor-progress conversation differs from recovery")]
ProgressConversationMismatch,
#[error("cursor-progress participant differs from recovery")]
ProgressParticipantMismatch,
#[error("cursor-progress epoch differs from recovery")]
ProgressEpochMismatch,
#[error("cursor-progress marker differs from recovery")]
ProgressMarkerMismatch,
#[error("cursor-progress through boundary differs from its marker")]
ProgressThroughMismatch,
#[error("marker-delivery participant differs from cursor progress")]
DeliveryParticipantMismatch,
#[error("marker-delivery epoch differs from cursor progress")]
DeliveryEpochMismatch,
#[error("marker-delivery sequence differs from cursor progress")]
DeliveryMarkerMismatch,
#[error("terminal conversation differs from recovery")]
TerminalConversationMismatch,
#[error("terminal participant differs from recovery")]
TerminalParticipantMismatch,
#[error("terminal epoch differs from recovery")]
TerminalEpochMismatch,
#[error("composed terminal kind and cause class disagree")]
ComposedTerminalKindCause,
#[error("composed terminal order differs from the enclosing Attached order")]
ComposedTerminalOrder,
#[error("composed terminal pending source does not precede Attached")]
ComposedPendingSourceOrder,
#[error("recovered reservation source does not precede Attached")]
ComposedRecoveredSourceOrder,
#[error("only Pending Died may consume a recovered finalizer reservation")]
ComposedRecoveredReservationKind,
#[error("composed terminal pending source row disagrees with its audit")]
ComposedPendingSourceMismatch,
#[error("composed terminal recovered reservation row disagrees with its audit")]
ComposedRecoveredReservationMismatch,
#[error("open recovered finalizer reservations exceed the signed identity-slot bound")]
ComposedRecoveredReservationCapacity,
#[error("composed terminal disagrees with replay binding prestate")]
ComposedReplayStateMismatch,
}
#[derive(Debug, thiserror::Error)]
pub enum OperationLogError {
#[error(transparent)]
Durability(#[from] DurabilityError),
#[error("routed stream refused: {0}")]
RoutedStream(#[source] RoutedStreamRefusal),
#[error(transparent)]
Bridge(#[from] liminal::durability::bridge::BridgeError),
#[error("participant production log serialization failed: {0}")]
Serialization(#[from] serde_json::Error),
#[error("unsupported participant production log schema version {0}")]
SchemaVersion(u8),
#[error(
"participant production log row at sequence {sequence} carries the wrong retained-charge audit form for schema version {schema_version}"
)]
RetainedChargeForm { sequence: u64, schema_version: u8 },
#[error(
"participant production log schema regressed at sequence {sequence}: previous {previous}, actual {actual}"
)]
SchemaVersionTransition {
sequence: u64,
previous: u8,
actual: u8,
},
#[error("participant production log expected sequence {expected}, found {actual}")]
Sequence {
expected: u64,
actual: u64,
},
#[error("participant production log append expected {expected}, got {actual}")]
AssignedSequence {
expected: u64,
actual: u64,
},
#[error("participant production log entry carries zero generation")]
ZeroGeneration,
#[error("durable participant row at sequence {sequence} was refused during restore")]
CorruptRow {
sequence: u64,
},
#[error("prune receipt {key} refused its proof: {source}")]
PruneReceipt {
key: String,
#[source]
source: super::prune::PruneProofError,
},
#[error("v2 Attached row at sequence {sequence} has no durable fenced proof")]
V2AttachedFencedProofUnavailable { sequence: u64 },
#[error("v2 Attached row at sequence {sequence} has contradictory mode evidence")]
V2AttachedModeMismatch { sequence: u64 },
#[error("v3 fenced Attached proof at sequence {sequence} was refused: {reason}")]
FencedAttachProof {
sequence: u64,
reason: FencedAttachProofRefusal,
},
#[error("participant production retained-charge count exceeds u64")]
RetainedChargeCount,
#[error("reconstructed fate operation drifted from durable sequence {sequence}")]
FateReplayDrift { sequence: u64 },
#[error("participant production log row timestamp: {0}")]
Clock(#[from] FactsError),
#[error("participant conversation registry snapshot refused: {0}")]
RegistrySnapshot(#[source] super::registry_snapshot::RegistrySnapshotError),
#[error(
"participant conversation registry row {sequence} for conversation {conversation_id} refused: {refusal}"
)]
RegistryRow {
sequence: u64,
conversation_id: u64,
refusal: RegistryRowRefusal,
},
#[error("participant conversation {conversation_id} is retired")]
ConversationRetired {
conversation_id: u64,
},
}
impl From<RoutedStreamError> for OperationLogError {
fn from(error: RoutedStreamError) -> Self {
match error {
RoutedStreamError::Store(original) => Self::Durability(original),
RoutedStreamError::Refusal(refusal) => Self::RoutedStream(refusal),
}
}
}
impl From<super::operation_batch::CheckpointStageError> for OperationLogError {
fn from(error: super::operation_batch::CheckpointStageError) -> Self {
use super::operation_batch::CheckpointStageError;
match error {
CheckpointStageError::Store(original) => Self::Durability(original),
CheckpointStageError::Checkpoint(original) => {
Self::RoutedStream(RoutedStreamRefusal::Checkpoint(Box::new(original)))
}
CheckpointStageError::Locator(original) => {
Self::RoutedStream(RoutedStreamRefusal::CheckpointLocator(original))
}
CheckpointStageError::BatchRefused => {
Self::RoutedStream(RoutedStreamRefusal::BatchRefused)
}
CheckpointStageError::RouteMismatch => {
Self::RoutedStream(RoutedStreamRefusal::CheckpointRouteMismatch)
}
CheckpointStageError::PositionRegression => {
Self::RoutedStream(RoutedStreamRefusal::CheckpointPositionRegression)
}
CheckpointStageError::BodyMismatch => {
Self::RoutedStream(RoutedStreamRefusal::CheckpointBodyMismatch)
}
}
}
}
#[derive(Debug, thiserror::Error)]
pub(super) enum StreamKeyRefusal {
#[error(transparent)]
Store(#[from] DurabilityError),
#[error("participant conversation {conversation_id} is retired")]
Retired {
conversation_id: u64,
},
}
impl From<StreamKeyRefusal> for OperationLogError {
fn from(refusal: StreamKeyRefusal) -> Self {
match refusal {
StreamKeyRefusal::Store(store) => Self::Durability(store),
StreamKeyRefusal::Retired { conversation_id } => {
Self::ConversationRetired { conversation_id }
}
}
}
}