#[non_exhaustive]pub enum StoreError<A, EncErr, DecErr> {
Conflict {
stream_id: ErrorId,
expected: Option<Version>,
actual: Option<Version>,
},
StreamNotFound {
stream_id: ErrorId,
},
Adapter(A),
Encode(EncErr),
Decode(DecErr),
Kernel(KernelError),
VersionOverflow,
EnvelopeSynthesis(ForDecodeError),
Envelope(EnvelopeError),
}Expand description
Errors from the event store layer.
Generic over adapter (A), encode (EncErr), and decode (DecErr) error
types — zero allocation, no Box<dyn Error>.
EncErr and DecErr are independent so write-only and read-only codecs
can each set the unused side to Infallible. For the common case where
a single underlying format powers both directions, the implementor picks
the same Error associated type on both Encode and Decode impls and
EncErr == DecErr falls out without a where-clause.
Upcast errors are not part of this type — the no-upcaster
load / save
path can’t produce them. When the user calls
EventStore::load_with (passing an
upcast function), the result wraps StoreError in
LoadWithError alongside the user’s upcast error type.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
Conflict
Optimistic concurrency conflict.
StreamNotFound
Stream not found.
Adapter(A)
Database adapter failure.
Encode(EncErr)
Serialization failure on the write path.
Decode(DecErr)
Deserialization failure on the read path.
Kernel(KernelError)
Kernel error during replay (e.g. version mismatch, rehydration limit).
VersionOverflow
Version overflow: cannot advance past u64::MAX.
EnvelopeSynthesis(ForDecodeError)
Failure while synthesizing a fresh envelope for codec decode.
Reachable only from upcaster-driven paths
(EventStore::load_with):
after the user’s upcast transforms the event, a fresh aligned
envelope is built from the transformed event_type + payload via
PersistedEnvelope::for_decode.
The build can fail at the value-newtype boundary (oversize
event_type/payload), the wire encode (FrameLengthOverflow),
or the envelope construction (range invariants).
Envelope(EnvelopeError)
Envelope construction rejected user-supplied bytes (payload exceeded its size cap, or another value-newtype invariant).
Raised on the save path when an encoded payload violates the
invariants enforced by the PendingEnvelope
builder. The schema-version-zero case is not reachable from the
typed-repository save path because SchemaVersion is constructed
from NonZeroU32.
Implementations§
Source§impl<A, EncErr, DecErr> StoreError<A, EncErr, DecErr>
impl<A, EncErr, DecErr> StoreError<A, EncErr, DecErr>
Sourcepub const fn is_conflict(&self) -> bool
pub const fn is_conflict(&self) -> bool
Returns true if this is an optimistic-concurrency Conflict.
Conflict is the one error the store can assert a semantic fact
about that the consumer cannot infer otherwise: the expected version
was stale, so reloading the aggregate and re-running the (pure,
side-effect-free) decision will likely succeed. It is the natural
predicate for a consumer-owned retry loop — e.g. a supervising actor
retrying load → handle → save, or a tower::retry::Policy /
backon .when(|e| e.is_conflict()).
mnesis deliberately ships no retry machinery: classifying other errors as retryable (transient adapter I/O, say) needs context only the consumer has, and the loop, backoff, and sleep are runtime concerns. This predicate is the entire retry-facing surface.
Trait Implementations§
Source§impl<A, EncErr, DecErr> ConflictPredicate for StoreError<A, EncErr, DecErr>
impl<A, EncErr, DecErr> ConflictPredicate for StoreError<A, EncErr, DecErr>
Source§fn is_conflict(&self) -> bool
fn is_conflict(&self) -> bool
true iff this error is an optimistic-concurrency conflict.Source§impl<A, EncErr, DecErr> Display for StoreError<A, EncErr, DecErr>
impl<A, EncErr, DecErr> Display for StoreError<A, EncErr, DecErr>
Source§impl<A, EncErr, DecErr> Error for StoreError<A, EncErr, DecErr>
impl<A, EncErr, DecErr> Error for StoreError<A, EncErr, DecErr>
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
Source§impl<A, EncErr, DecErr> From<EnvelopeError> for StoreError<A, EncErr, DecErr>
impl<A, EncErr, DecErr> From<EnvelopeError> for StoreError<A, EncErr, DecErr>
Source§fn from(source: EnvelopeError) -> Self
fn from(source: EnvelopeError) -> Self
Source§impl<A, EncErr, DecErr> From<KernelError> for StoreError<A, EncErr, DecErr>
impl<A, EncErr, DecErr> From<KernelError> for StoreError<A, EncErr, DecErr>
Source§fn from(source: KernelError) -> Self
fn from(source: KernelError) -> Self
Source§impl<A, EncErr, DecErr, UpErr> From<StoreError<A, EncErr, DecErr>> for LoadWithError<A, EncErr, DecErr, UpErr>
impl<A, EncErr, DecErr, UpErr> From<StoreError<A, EncErr, DecErr>> for LoadWithError<A, EncErr, DecErr, UpErr>
Source§fn from(source: StoreError<A, EncErr, DecErr>) -> Self
fn from(source: StoreError<A, EncErr, DecErr>) -> Self
Auto Trait Implementations§
impl<A, EncErr, DecErr> Freeze for StoreError<A, EncErr, DecErr>
impl<A, EncErr, DecErr> RefUnwindSafe for StoreError<A, EncErr, DecErr>
impl<A, EncErr, DecErr> Send for StoreError<A, EncErr, DecErr>
impl<A, EncErr, DecErr> Sync for StoreError<A, EncErr, DecErr>
impl<A, EncErr, DecErr> Unpin for StoreError<A, EncErr, DecErr>
impl<A, EncErr, DecErr> UnsafeUnpin for StoreError<A, EncErr, DecErr>
impl<A, EncErr, DecErr> UnwindSafe for StoreError<A, EncErr, DecErr>
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
Source§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
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
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> LayoutRaw for T
impl<T> LayoutRaw for T
Source§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
Source§impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
Source§unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
Source§fn resolve_niched(out: Place<NichedOption<T, N1>>)
fn resolve_niched(out: Place<NichedOption<T, N1>>)
out indicating that a T is niched.