Ниже показан английский оригинал.
Errors
SqlxBrokerError is the inbox's one error type: connecting, statements, the schema, declarations, leases, transactions, publishes, and a closed broker.
Every variant about a subscription names the subscription, the table and the row type, so one line of a log says where to look.
The database's own error is its source.
| Variant | When |
|---|---|
Connect | the connect could not take a connection from the pool |
Url | the connect could not read the URL of a broker made with from_url |
Backend | an AnyPool reached a database whose dialect's feature is off |
Schema | a statement failed to prepare at startup: the table lacks a table or a column the description names |
Dialect | the dialect could not build a statement for the table |
ServerTooOld | the server is older than the statements of the table's form need |
Declaration | the mount declared what the table cannot carry |
ConnectionLimit | a subscription on dedicated threads would pass the broker's connection limit |
AlreadySubscribed | a second subscription to one queue on the same broker |
Sqlx | a statement failed while the subscription ran |
BatchRolledBack | an earlier settlement of a batch failed, so the batch rolls back |
LeaseLost | in the lease form, the lease ran out and another claim took the row, so the settlement took no effect |
TransactionHeld | in transactional mode, the handler kept its transaction past its return |
Listen | listen_notify could not listen on the table's channel |
Publish | the service's Publish failed |
Header | the publish carries a header the table cannot hold byte for byte |
NoRoute | no route leads the name to a table |
Closed | the broker was shut down, and a handle outlived it |
A service meets the error in three places.
A failed startup carries it as the source of the runtime's error, and the service exits before it reads a row.
A publish from a handler returns it inside the core's PublishError, and the handler decides how its delivery settles.
A settlement that fails, such as LeaseLost, goes to the log with the row's id.
The enum is #[non_exhaustive], so a match on it ends with a wildcard arm.
Example
An invoice the database refuses to write is logged with its cause, and the payment waits a minute before it is billed again.
- Macros
- Manual
#[subscriber(InboxQueue::<PaymentJob>::new("payments"))]
async fn bill(payment: &Payment, Out(invoices): Out<impl Publisher, Invoices>) -> HandlerOutcome {
let invoice = Invoice {
payment: payment.id,
};
if let Err(error) = invoices.message(&invoice).publish().await {
// The error names the destination, the table and the database's reason.
tracing::warn!(subscription = "payments", payment.id, %error, "invoice not written");
return HandlerOutcome::retry_after(Duration::from_secs(60));
}
HandlerOutcome::ack()
}
struct Bill;
impl<Entry> Handle<Payment, (), Outs<(Entry,)>> for Bill
where
Entry: OutEntry<Invoices, Wire: Publisher>,
{
async fn handle(
&self,
payment: &Payment,
outs: &Outs<(Entry,)>,
_ctx: &mut Context<'_>,
) -> Result<(), HandlerOutcome> {
let invoice = Invoice {
payment: payment.id,
};
outs.get(Invoices)
.message(&invoice)
.publish()
.await
.map_err(|error| {
// The error names the destination, the table and the database's reason.
tracing::warn!(subscription = "payments", payment.id, %error, "invoice not written");
HandlerOutcome::retry_after(Duration::from_secs(60))
})
}
}