pub enum Fault<L: LaneProfile = AllLanes> {
Denied(L::Denied),
Transient(L::Transient),
Fatal(L::Fatal),
}Expand description
Fail minus the Rejected lane: what an operation that cannot reject
(nothing about it is the caller’s to correct) returns. Reads return
Fault<L>; writes return Fail<{Entity}ConstraintViolation, L> — the type
itself says whether a call can ever hand back a domain outcome.
Variants§
Implementations§
Source§impl<L: LaneProfile> Fault<L>
impl<L: LaneProfile> Fault<L>
Sourcepub fn lanes(&self) -> LaneRef<'_, Infallible>
pub fn lanes(&self) -> LaneRef<'_, Infallible>
A borrowed view of the current lane.
Source§impl Fault
impl Fault
Sourcepub fn classify(e: &(dyn Error + 'static)) -> Fault
pub fn classify(e: &(dyn Error + 'static)) -> Fault
Classify an erased error at a boundary that only has &(dyn Error + 'static) — e.g. &*boxed for a Box<dyn Error> that is not
Send/Sync and so cannot become a lane payload’s source
(Fatal’s and Transient’s sources are Arc<dyn Error + Send + Sync>, by design — see the crate README). No Send/Sync bound is
needed here: every step only ever borrows e. Call before the next
.await — the chain being walked may not be Send.
- A lane payload anywhere in the chain wins, carried through intact
— kind, context, and (now
Send/Sync, having been cloned out) its own original source. - Else, for each blessed foreign type whose
classify-*feature is enabled (sqlx::Error,serde_json::Error,reqwest::Error, in that order), the first one found anywhere in the chain is classified exactly as that feature’simpl Classifywould — with the error’s message ascontextin place of the source this function cannot move out of a shared reference. - Else
Fatal(FatalKind::Dependency), withmessage_chain(private) ascontext.
Rule 3 is a safety default, not a shrug: an error this function
cannot otherwise classify must still surface as something a boundary
pages on, never silently as nothing. A lane payload found by this
rule may itself be a Denied — narrowing it away, if the boundary
has no subject, is the caller’s explicit next step (see
Fault::narrow_denied).
Source§impl<L: LaneProfile> Fault<L>
impl<L: LaneProfile> Fault<L>
pub fn lane(&self) -> Lane
pub fn is_transient(&self) -> bool
pub fn is_fatal(&self) -> bool
pub fn is_denied(&self) -> bool
Sourcepub fn message(&self) -> String
pub fn message(&self) -> String
The operator-safe one-line text for this failure — exactly what
record writes to exception.message, for a boundary that must
persist it rather than (or as well as) record it. Transient/
Fatal: the whole source() chain joined with ": ". Denied: its
Display.
Sourcepub fn narrow_transient(self, attempts: u32) -> Fault<WithoutTransient<L>>
pub fn narrow_transient(self, attempts: u32) -> Fault<WithoutTransient<L>>
Consumes the Transient lane, yielding the same profile with its
transient slot disabled. attempts is what the retry loop counted; an
exhausted transient becomes Fatal(Exhausted) with the last transient
as its source.
Sourcepub fn narrow_denied(self) -> Fault<WithoutDenied<L>>
pub fn narrow_denied(self) -> Fault<WithoutDenied<L>>
Narrows away the Denied lane: a denial at a boundary with no
subject (code running as the system) becomes Fatal(Denied) with
the Denied as its source.
Source§impl<L: LaneProfile<Denied = Denied>> Fault<L>
Borrowed lane accessors. min_exhaustive_patterns lets a by-value match
name only the lanes a profile enables, but a borrowed match still demands an
arm for every variant. These accessors are the borrowed form, so no caller
ever has to write a match *never {} arm. Each is available only when the
profile enables that lane, so e.as_denied() on a no-denial profile is a
compile error rather than a permanent None.
impl<L: LaneProfile<Denied = Denied>> Fault<L>
Borrowed lane accessors. min_exhaustive_patterns lets a by-value match
name only the lanes a profile enables, but a borrowed match still demands an
arm for every variant. These accessors are the borrowed form, so no caller
ever has to write a match *never {} arm. Each is available only when the
profile enables that lane, so e.as_denied() on a no-denial profile is a
compile error rather than a permanent None.
Source§impl<L: LaneProfile<Transient = Transient>> Fault<L>
impl<L: LaneProfile<Transient = Transient>> Fault<L>
pub fn as_transient(&self) -> Option<&Transient>
pub fn is_congestion(&self) -> bool
Sourcepub fn is_contention(&self) -> bool
pub fn is_contention(&self) -> bool
Trait Implementations§
Source§impl<L: LaneProfile> Display for Fault<L>
impl<L: LaneProfile> Display for Fault<L>
Source§impl<L: LaneProfile> Error for Fault<L>
impl<L: LaneProfile> Error for Fault<L>
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<W: IntoLanes<Rejected = Infallible>, M: LaneProfile> From<W> for Fault<M>where
W::Shape: IntoFault,
<W::Lanes as LaneProfile>::Denied: Into<M::Denied>,
<W::Lanes as LaneProfile>::Transient: Into<M::Transient>,
<W::Lanes as LaneProfile>::Fatal: Into<M::Fatal>,
? into a Fault: only for a source that never rejects, and only into a
profile that holds all of the source’s lanes. A rejection, or a mixed
wrapper, entering a Fault function stays an explicit narrowing
(narrow_rejected), never a silent ?.
impl<W: IntoLanes<Rejected = Infallible>, M: LaneProfile> From<W> for Fault<M>where
W::Shape: IntoFault,
<W::Lanes as LaneProfile>::Denied: Into<M::Denied>,
<W::Lanes as LaneProfile>::Transient: Into<M::Transient>,
<W::Lanes as LaneProfile>::Fatal: Into<M::Fatal>,
? into a Fault: only for a source that never rejects, and only into a
profile that holds all of the source’s lanes. A rejection, or a mixed
wrapper, entering a Fault function stays an explicit narrowing
(narrow_rejected), never a silent ?.
Why this is coherent with the reflexive From<T> for T: Fault<M>’s own
Shape is kind::Fault, which is not [kind::IntoFault], and every type
and marker involved is local to errlanes. Do not replace the marker bound
with associated-type equality across several impls on a generic W: two
such impls overlap (rust-lang/rust#20400).
Source§impl<L: LaneProfile> Laned for Fault<L>
impl<L: LaneProfile> Laned for Fault<L>
type WithoutTransient = Fault<<L as LaneProfile>::WithoutTransient>
fn lane(&self) -> Lane
Source§fn level(&self) -> Level
fn level(&self) -> Level
Lane::level), overridden only by a Rejected outcome’s
Rejection::level.fn narrow_transient(self, attempts: u32) -> Self::WithoutTransient
Source§fn message(&self) -> String
fn message(&self) -> String
record writes to exception.message, for a boundary that must
persist it rather than (or as well as) record it. Transient/
Fatal: the whole source() chain joined with ": ". Denied: its
Display. Rejected: the rejection’s code, never its message
(display discipline — a rejection’s message may embed caller-supplied
input).