下面显示的是英文原文。
Errors
RedisError is the one error type of the crate: connect, publish, subscribe, stream reads, shutdown, transactions and refused options.
Each variant names the step that failed.
The fred error behind it is its source, so the client library's types stay out of the crate's API.
| Variant | When |
|---|---|
Connect | the address could not be parsed, the server did not answer, or the login was refused |
Publish | the server refused a write, such as a list push to a key that holds a stream (WRONGTYPE) |
Subscribe | a consumer group could not be created, or a subscription could not open |
Stream | a stream read or an acknowledgement failed |
ShutDown | a publisher, a delivery or a transaction was used after the broker shut down |
InvalidOptions | the settings cannot work together, such as a bare name with no default group |
ServerTooOld | a claiming subscription met a server older than Redis 8.4 |
TransactionBusy, NoTransaction | a transaction was begun twice on one publisher, or ended with none open |
Flush | a pipelined window failed to send what it owed |
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 ledger entry the server refuses is logged with its cause, and the order is settled as a retry. The subscription claims the order back once it has been idle thirty seconds.
- Macros
- Manual
/// A retried order stays pending and comes back once it has been idle for thirty seconds.
#[subscriber(RedisStream::claiming("orders", Duration::from_secs(30)).group("workers"))]
async fn book(order: &Order, Out(ledger): Out<impl Publisher, Ledger>) -> HandlerOutcome {
let entry = LedgerEntry {
order_id: order.id,
amount: order.amount,
};
if let Err(err) = ledger.message(&entry).publish().await {
// The error carries the server's answer, such as `WRONGTYPE`.
tracing::warn!(subscription = "orders", order.id, error = %err, "ledger entry not written");
return HandlerOutcome::retry();
}
HandlerOutcome::ack()
}
struct Book;
impl<Entry> Handle<Order, (), Outs<(Entry,)>> for Book
where
Entry: OutEntry<Ledger, Wire: Publisher>,
{
async fn handle(
&self,
order: &Order,
outs: &Outs<(Entry,)>,
_ctx: &mut Context<'_>,
) -> Result<(), HandlerOutcome> {
let entry = LedgerEntry {
order_id: order.id,
amount: order.amount,
};
if let Err(err) = outs.get(Ledger).message(&entry).publish().await {
// The error carries the server's answer, such as `WRONGTYPE`.
tracing::warn!(subscription = "orders", order.id, error = %err, "ledger entry not written");
return Err(HandlerOutcome::retry());
}
Ok(())
}
}
/// A retried order stays pending and comes back once it has been idle for thirty seconds.
fn orders() -> RedisStream {
RedisStream::claiming("orders", Duration::from_secs(30)).group("workers")
}