Ниже показан английский оригинал.
Errors
AmqpError is the crate's one error: connect, publish, subscribe, consume, declare, request, timeout, closed, transaction and options.
Each variant names the step that failed.
The lapin error behind it is its source, so the client library's types stay out of the crate's API.
| Variant | When |
|---|---|
Connect | the URI did not parse, the server was unreachable or refused the login, or the close failed |
Publish | the server refused a message, such as a body over its 16 MiB max_message_size, or did not confirm it |
Subscribe | a channel, its prefetch or its consumer could not be opened, such as on a queue the server does not have |
Consume | an open consumer failed to receive |
Declare | the server refused an exchange, a queue or a binding the service declares |
Request | a request could not be sent, or its reply could not be received |
RequestTimeout | no reply arrived within the requester's deadline |
Closed | a publisher or a requester was used after the shutdown; it names the target |
Transaction | a transaction call came out of order: a commit with none open, or a second begin |
InvalidOptions | the settings cannot work together, such as half of a quorum queue's retry declaration |
A service meets the error in two places.
A failed startup carries it as the source of the runtime's error, and the service exits before it consumes anything.
A publish from a handler returns it inside 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
A shipment the server refuses is logged with its cause, and the order is dropped to the queue's dead-letter exchange.
- Macros
- Manual
#[subscriber(RabbitQueue::new("orders").dead_letter_exchange("orders.failed"))]
async fn ship(order: &Order, Out(shipments): Out<impl Publisher, Shipments>) -> HandlerOutcome {
let shipment = Shipment {
order_id: order.id,
labels: (1..=order.parcels)
.map(|parcel| format!("{}-{parcel:07}", order.id))
.collect(),
};
if let Err(err) = shipments.message(&shipment).publish().await {
// The error names the step that failed and the server's reason.
tracing::warn!(subscription = "orders", order.id, error = %err, "shipment not published");
return HandlerOutcome::drop();
}
HandlerOutcome::ack()
}
struct Ship;
impl<Entry> Handle<Order, (), Outs<(Entry,)>> for Ship
where
Entry: OutEntry<Shipments, Wire: Publisher>,
{
async fn handle(
&self,
order: &Order,
outs: &Outs<(Entry,)>,
_ctx: &mut Context<'_>,
) -> Result<(), HandlerOutcome> {
let shipment = Shipment {
order_id: order.id,
labels: (1..=order.parcels)
.map(|parcel| format!("{}-{parcel:07}", order.id))
.collect(),
};
if let Err(err) = outs.get(Shipments).message(&shipment).publish().await {
// The error names the step that failed and the server's reason.
tracing::warn!(subscription = "orders", order.id, error = %err, "shipment not published");
return Err(HandlerOutcome::drop());
}
Ok(())
}
}
fn orders() -> RabbitQueue {
RabbitQueue::new("orders").dead_letter_exchange("orders.failed")
}