跳到主要内容
本页尚未翻译

下面显示的是英文原文。

Failures

What a subscriber does when its handler panics or a payload cannot decode, set per subscriber with on_failure.

A subscriber carries two policies: one for a handler panic, one for a delivery that cannot decode. A panic fails fast by default, and a test reads it with panicked: a loud error names the subscription, the service shuts down gracefully, and run returns an error, so an orchestrator restarts it. Fail fast takes effect under an unwinding panic profile; with panic = "abort" the process is already gone. A decode failure drops the delivery by default: one malformed payload does not stop the consumer, and assert_last_failed_to_decode checks it in a test. A decode failure is a payload the codec rejects, a header contract that does not parse, a missing carried value, or a delivery the broker reports unreadable. Each policy is a FailurePolicy: fail_fast, drop, retry, retry_after(delay) or skip. drop, retry and retry_after(delay) settle the way the handler outcomes of the same name do. skip acks the delivery to move past it; the message is gone and was never handled. retry and retry_after bring the delivery back, so a payload that never decodes keeps coming back. The attribute takes on_failure(panic = .., decode = ..), with either key alone; the manual form takes a FailurePolicies value.

Example​

/// No clause: a payload that cannot decode is dropped, and a panic stops the service.
#[subscriber("orders")]
async fn fulfil(order: &Order) -> HandlerOutcome {
assert_ne!(order.id, 0, "an order without an id reached fulfilment");
HandlerOutcome::ack()
}

Move past every failure​

/// An audit trail moves past anything it cannot process: both failures ack the delivery.
#[subscriber("orders", on_failure(panic = skip, decode = skip))]
async fn audit(order: &Order) -> HandlerOutcome {
assert_ne!(order.id, 0, "an order without an id reached the audit");
HandlerOutcome::ack()
}

A payload to read later​

const SCHEMA_ROLLOUT: Duration = Duration::from_secs(60);

/// Producers roll a schema change out first: a payload this version cannot read yet comes
/// back in a minute instead of being dropped. A panic still stops the service.
#[subscriber("orders", on_failure(decode = retry_after(SCHEMA_ROLLOUT)))]
async fn accept(order: &Order) -> HandlerOutcome {
tracing::info!(order.id, "accepted");
HandlerOutcome::ack()
}