ruststream_fred/error.rs
1//! Error type returned by Redis broker operations.
2
3use std::error::Error as StdError;
4
5use thiserror::Error;
6
7/// Errors surfaced by the Redis broker implementation.
8#[derive(Debug, Error)]
9#[non_exhaustive]
10pub enum RedisError {
11 /// Failed to establish or use the underlying `fred` connection.
12 #[error("redis connection error: {0}")]
13 Connect(#[source] Box<dyn StdError + Send + Sync>),
14
15 /// Failed to publish (`XADD`) a message to a stream.
16 #[error("redis publish error: {0}")]
17 Publish(#[source] Box<dyn StdError + Send + Sync>),
18
19 /// Failed to open a subscription (consumer-group creation or the first read).
20 #[error("redis subscribe error: {0}")]
21 Subscribe(#[source] Box<dyn StdError + Send + Sync>),
22
23 /// A stream read (`XREADGROUP` / `XAUTOCLAIM`) or acknowledgement (`XACK`) failed.
24 #[error("redis stream error: {0}")]
25 Stream(#[source] Box<dyn StdError + Send + Sync>),
26
27 /// The operation ran through a handle aliasing a connection that was already shut down
28 /// ([`ConnectedBroker::shutdown`](ruststream::ConnectedBroker::shutdown)).
29 ///
30 /// The lifecycle ladder makes misuse by the owner of the connected broker a compile error;
31 /// publishers handed out before the shutdown outlive it, so their operations report this
32 /// instead of running against a dead pool.
33 #[error("the redis broker connection is shut down")]
34 ShutDown,
35
36 /// `begin_transaction` was called while a transaction is already open on this publisher handle.
37 #[error("a transaction is already open on this publisher handle")]
38 TransactionBusy,
39
40 /// `commit` or `abort` was called with no open transaction on this publisher handle.
41 #[error("no transaction is open on this publisher handle")]
42 NoTransaction,
43
44 /// The supplied subscription descriptor combines fields in a way the broker cannot honour
45 /// (for example a [`RedisStream`](crate::RedisStream) with no consumer group, or a bare-string
46 /// subscription with no broker-wide default group).
47 #[error("invalid subscribe options: {0}")]
48 InvalidOptions(String),
49
50 /// The connected server is older than the subscription's read mode needs.
51 ///
52 /// [`RedisStream::claiming`](crate::RedisStream::claiming) issues `XREADGROUP ... CLAIM`,
53 /// which Redis 8.4.0 added. The check runs where the subscription resolves against the
54 /// connected broker, once and before the first read, so the service fails at startup with
55 /// both versions named instead of meeting a syntax error on its first message.
56 ///
57 /// The message is the whole error: it already names the subscription, the mode and the two
58 /// versions, and a prefix would only repeat them.
59 #[error("{0}")]
60 ServerTooOld(String),
61
62 /// A window of a `.pipeline()` subscription failed to send what it owed.
63 ///
64 /// Reported once, on the subscription's delivery stream, and the message names the
65 /// subscription, how many commands the flush carried and how many failed. On the forms that
66 /// settle, the entries whose settles failed stay pending and are delivered again.
67 #[error("{0}")]
68 Flush(String),
69}
70
71impl RedisError {
72 /// Wraps a `fred` error as a [`RedisError::Stream`].
73 pub(crate) fn stream(err: fred::error::Error) -> Self {
74 Self::Stream(Box::new(err))
75 }
76
77 /// Wraps a `fred` error as a [`RedisError::Subscribe`].
78 pub(crate) fn subscribe(err: fred::error::Error) -> Self {
79 Self::Subscribe(Box::new(err))
80 }
81
82 /// Wraps a `fred` error as a [`RedisError::Publish`].
83 pub(crate) fn publish(err: fred::error::Error) -> Self {
84 Self::Publish(Box::new(err))
85 }
86}