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

下面显示的是英文原文。

Errors

AmqpError is the one error type of the crate: connect, session, attach, publish, receive, request, transaction and a body with no bytes.

Each variant names the step that failed. The client's error behind it is its source, so the fe2o3-amqp types stay out of the crate's API.

VariantWhen
Connectthe URL, the socket, TLS, the login or the AMQP open failed, or the connection failed to close at shutdown
Sessionthe broker refused a session, the publishers' or a subscription's
Attachthe broker refused a link: a subscription's receiver, a publisher's sender, a request's reply link
Detacha link failed to close at shutdown
Publishthe connection failed while a message was sent
PublishNotAcceptedthe broker settled a published message as rejected, released or modified, so the message is not on the broker
Receivethe connection failed while a subscription received
UnsupportedBodya delivery's body is an AMQP value that is neither binary nor a string; the delivery is rejected, and the runtime logs the error
RequestTimeouta request had no reply within its timeout
NotConnecteda publisher, a subscription or a transaction was used before the connect or after the shutdown
InvalidAddressa subscription's address is empty
Transactiona transaction step was called in a state that cannot serve it (transaction feature)

A service meets the error in two places. A failed startup carries it as a source of the runtime's error, and the service exits before it reads anything. A publish from a handler returns it as the source of the core's PublishError, and the handler decides how the delivery settles. The enum is #[non_exhaustive], so a match on it ends with a wildcard arm.

Example​

The handler sends each shipment to the warehouse address its order names. A shipment the broker refuses drops the order, since sending it again meets the same answer; any other failure retries it.

#[subscriber(AmqpAddress::queue("orders"))]
async fn ship(order: &Order, Out(warehouses): Out<impl Publisher>) -> HandlerOutcome {
let shipment = Shipment { order_id: order.id };
let sent = warehouses
.message(&shipment)
.to(order.warehouse.as_str())
.publish()
.await;
match sent {
Ok(()) => HandlerOutcome::ack(),
Err(err) => {
tracing::warn!(subscription = "orders", order.id, error = %err, "shipment not sent");
if refused_by_the_broker(&err) {
HandlerOutcome::drop()
} else {
HandlerOutcome::retry()
}
}
}
}

/// Whether the broker settled the message with an outcome other than accepted. Sending it again
/// meets the same answer, while a connection that failed under the publish may be back by the next
/// attempt.
fn refused_by_the_broker(err: &(dyn Error + 'static)) -> bool {
let mut cause = Some(err);
while let Some(err) = cause {
if let Some(AmqpError::PublishNotAccepted { .. }) = err.downcast_ref() {
return true;
}
cause = err.source();
}
false
}