pub enum Fail<D, L: LaneProfile = AllLanes> {
Rejected(D),
Denied(L::Denied),
Transient(L::Transient),
Fatal(L::Fatal),
}Expand description
The generic view over a domain rejection D, before retries have run.
Display discipline: Display’s Rejected arm keeps
its rejected: {d} prefix for logs, but no boundary may build a
user-facing message from to_string() — a rejection’s message may embed
caller-supplied input. Use as_rejected and
Rejection::code instead: record_fail keys error.code off the code,
never the message, and a GraphQL boundary should do the same for its error
extension.
Variants§
Implementations§
Source§impl<D, L: LaneProfile<Denied = Denied>> Fail<D, L>
impl<D, L: LaneProfile<Denied = Denied>> Fail<D, L>
Source§impl<D, L: LaneProfile<Transient = Transient>> Fail<D, L>
impl<D, L: LaneProfile<Transient = Transient>> Fail<D, 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
See [TransientKind::is_contention].
Source§impl<D, L: LaneProfile<Fatal = Fatal>> Fail<D, L>
impl<D, L: LaneProfile<Fatal = Fatal>> Fail<D, L>
Source§impl<D, L: LaneProfile> Fail<D, L>
impl<D, L: LaneProfile> Fail<D, L>
pub fn lane(&self) -> Lane
Sourcepub fn widen<P: Lift<D>, M: LaneProfile>(self) -> Fail<P, M>
pub fn widen<P: Lift<D>, M: LaneProfile>(self) -> Fail<P, M>
Widen the rejection and the lane profile without changing any
classification. The value-level form of [WidenResult::widen], with
the same single rule: P: Lift<D> is satisfied by a total From<D>
(through errlanes’ blanket, Unmapped = Infallible) and by a partial
#[lift(Source, unhandled = fatal)] mapping (Unmapped = Source),
whose unmapped cases demote to Fatal(Invariant) with the rejection
as their source — which is why a partial mapping requires the
destination to admit Fatal. The strict/partial choice is declared
once on the destination enum; the call site does not repeat it.
pub fn widen_with<P, M: LaneProfile<Fatal = Fatal>>( self, f: impl FnOnce(D) -> Result<P, Fatal>, ) -> Fail<P, M>
pub fn map_rejected<D2>(self, f: impl FnOnce(D) -> D2) -> Fail<D2, L>
Sourcepub fn rejected(self) -> Result<D, Fault<L>>
pub fn rejected(self) -> Result<D, Fault<L>>
Narrows to the domain outcome, or the non-domain fault. let d = e.rejected()?; propagates the fault into any enclosing Fail<_, L> (or
a Failure carrier) via the blanket From<Fault<L>>.
pub fn as_rejected(&self) -> Option<&D>
pub fn is_transient(&self) -> bool
pub fn is_fatal(&self) -> bool
pub fn is_denied(&self) -> bool
Sourcepub fn message(&self) -> Stringwhere
D: Rejection,
pub fn message(&self) -> Stringwhere
D: Rejection,
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. Rejected: the rejection’s code, never its message
(display discipline — a rejection’s message may embed caller-supplied
input).
Sourcepub fn narrow_transient(self, attempts: u32) -> Fail<D, WithoutTransient<L>>
pub fn narrow_transient(self, attempts: u32) -> Fail<D, WithoutTransient<L>>
Consumes the Transient lane, yielding the same rejection over L
with its transient slot disabled. An exhausted transient becomes
Fatal(Exhausted), carrying attempts and the last transient as its
source.
Sourcepub fn narrow_denied(self) -> Fail<D, WithoutDenied<L>>
pub fn narrow_denied(self) -> Fail<D, 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.
Sourcepub fn narrow_rejected(self) -> Fault<L>
pub fn narrow_rejected(self) -> Fault<L>
Narrows away the Rejected lane: a rejection at a boundary with no
caller to correct it is an invariant violation, and becomes
Fatal(Invariant) with the rejection as its source — the same rule
a partial #[lift(.., unhandled = fatal)] applies. Nothing is left
to reject, so the result is a Fault. with_opaque_source: d’s
Display may embed caller-supplied input (the same display
discipline Rejection documents everywhere else), so source()
still returns it for a handler or test to downcast_ref, but
message_chain must not walk into it.
Trait Implementations§
Source§impl<D: Error + 'static, L: LaneProfile> Error for Fail<D, L>
impl<D: Error + 'static, L: LaneProfile> Error for Fail<D, 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<D: Rejection, L: LaneProfile> Failure for Fail<D, L>
impl<D: Rejection, L: LaneProfile> Failure for Fail<D, L>
type Rejection = D
type Lanes = L
fn into_fail(self) -> Fail<Self::Rejection, Self::Lanes>
fn from_fail(f: Fail<Self::Rejection, Self::Lanes>) -> Self
fn as_fail(&self) -> &Fail<Self::Rejection, Self::Lanes>
fn lane(&self) -> Lane
fn is_transient(&self) -> bool
Source§impl<D, S: LaneProfile, L: LaneProfile> From<Fault<S>> for Fail<D, L>
The real blanket the Infallible encoding could not have: Fault<L> is not
Fail, so this does not overlap From<T> for T.
impl<D, S: LaneProfile, L: LaneProfile> From<Fault<S>> for Fail<D, L>
The real blanket the Infallible encoding could not have: Fault<L> is not
Fail, so this does not overlap From<T> for T.
Source§impl<W: Classify, D: Lift<W::Rejected, Unmapped = Infallible>, M: LaneProfile> From<W> for Fail<D, M>where
<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 Fail: the rejected part must be absorbed totally by D (no
decision left for the call site to make with .widen()); the wrapper’s
lanes must fit the destination’s profile. Replaces the narrower
impl<C: Rejection, D: From<C>, L> From<C> for Fail<D, L> — a bare
rejection is the W::Rejected = W, W::Lanes = NoLanes case of this.
impl<W: Classify, D: Lift<W::Rejected, Unmapped = Infallible>, M: LaneProfile> From<W> for Fail<D, M>where
<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 Fail: the rejected part must be absorbed totally by D (no
decision left for the call site to make with .widen()); the wrapper’s
lanes must fit the destination’s profile. Replaces the narrower
impl<C: Rejection, D: From<C>, L> From<C> for Fail<D, L> — a bare
rejection is the W::Rejected = W, W::Lanes = NoLanes case of this.
Auto Trait Implementations§
impl<D, L> Freeze for Fail<D, L>where
D: Freeze,
<L as LaneProfile>::Denied: Freeze,
<L as LaneProfile>::Transient: Freeze,
<L as LaneProfile>::Fatal: Freeze,
impl<D, L> RefUnwindSafe for Fail<D, L>where
D: RefUnwindSafe,
<L as LaneProfile>::Denied: RefUnwindSafe,
<L as LaneProfile>::Transient: RefUnwindSafe,
<L as LaneProfile>::Fatal: RefUnwindSafe,
impl<D, L> Send for Fail<D, L>where
D: Send,
<L as LaneProfile>::Denied: Send,
<L as LaneProfile>::Transient: Send,
<L as LaneProfile>::Fatal: Send,
impl<D, L> Sync for Fail<D, L>where
D: Sync,
<L as LaneProfile>::Denied: Sync,
<L as LaneProfile>::Transient: Sync,
<L as LaneProfile>::Fatal: Sync,
impl<D, L> Unpin for Fail<D, L>where
D: Unpin,
<L as LaneProfile>::Denied: Unpin,
<L as LaneProfile>::Transient: Unpin,
<L as LaneProfile>::Fatal: Unpin,
impl<D, L> UnsafeUnpin for Fail<D, L>where
D: UnsafeUnpin,
<L as LaneProfile>::Denied: UnsafeUnpin,
<L as LaneProfile>::Transient: UnsafeUnpin,
<L as LaneProfile>::Fatal: UnsafeUnpin,
impl<D, L> UnwindSafe for Fail<D, L>where
D: UnwindSafe,
<L as LaneProfile>::Denied: UnwindSafe,
<L as LaneProfile>::Transient: UnwindSafe,
<L as LaneProfile>::Fatal: UnwindSafe,
Blanket Implementations§
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<F> Laned for Fwhere
F: Failure,
<<F as Failure>::Lanes as LaneProfile>::Transient: NarrowTransient<<<F as Failure>::Lanes as LaneProfile>::Fatal>,
impl<F> Laned for Fwhere
F: Failure,
<<F as Failure>::Lanes as LaneProfile>::Transient: NarrowTransient<<<F as Failure>::Lanes as LaneProfile>::Fatal>,
type WithoutTransient = Fail<<F as Failure>::Rejection, <<F as Failure>::Lanes as LaneProfile>::WithoutTransient>
fn lane(&self) -> Lane
fn narrow_transient(self, attempts: u32) -> <F as Laned>::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).