Ниже показан английский оригинал.
Errors
NatsError is the one error type of the crate: connect, publish, subscribe, JetStream, shutdown, a request timeout and a closed connection.
Each variant names the step that failed.
The async-nats error behind it is its source, so the client's types stay out of the crate's API.
| Variant | When |
|---|---|
Connect | the client could not parse an address or reach the server, or the server refused the login |
Subscribe | the server refused a Core NATS subscription, such as one to a malformed subject |
JetStream | a stream or a consumer could not be found or created, a JetStream publish was refused or not stored, or an acknowledgement failed |
Publish | a publish was refused: a subject or a header the protocol cannot carry, a message over the server's payload limit, or a request nobody subscribes to |
RequestTimeout | a request received no reply within its timeout |
Closed | a publisher was used after the broker shut down; it carries the subject |
Shutdown | draining the connection at shutdown failed |
InvalidOptions | a descriptor names an empty subject, or a delayed copy is sent to a CoreSubject that holds a pattern |
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 reads 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 over the server's 1 MiB payload limit is refused. The handler logs the cause and settles the order as a retry.
- Macros
- Manual
#[subscriber("orders.created")]
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:06}", order.id))
.collect(),
};
if let Err(err) = shipments.message(&shipment).publish().await {
// The error names the subject and the server's reason.
tracing::warn!(subscription = "orders.created", order.id, error = %err, "shipment not published");
return HandlerOutcome::retry();
}
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:06}", order.id))
.collect(),
};
if let Err(err) = outs.get(Shipments).message(&shipment).publish().await {
// The error names the subject and the server's reason.
tracing::warn!(subscription = "orders.created", order.id, error = %err, "shipment not published");
return Err(HandlerOutcome::retry());
}
Ok(())
}
}