Skip to main content

mq_bridge/
errors.rs

1use thiserror::Error;
2
3/// Errors that can occur during message processing (handling or publishing).
4#[derive(Error, Debug)]
5pub enum ProcessingError {
6    /// A transient error occurred. The operation should be retried.
7    #[error("retryable error: {0}")]
8    Retryable(#[source] anyhow::Error),
9    /// A permanent error occurred. The operation should not be retried.
10    #[error("non-retryable error: {0}")]
11    NonRetryable(#[source] anyhow::Error),
12}
13
14pub type HandlerError = ProcessingError;
15pub type PublisherError = ProcessingError;
16
17/// Errors that can occur when consuming messages.
18#[derive(Error, Debug)]
19pub enum ConsumerError {
20    /// A transport-level or other error occurred that should trigger a reconnect.
21    #[error("consumer connection error: {0}")]
22    Connection(#[source] anyhow::Error),
23
24    /// A consumer gap was detected: the requested events were already garbage-collected.
25    #[error("consumer gap: requested offset {requested} but earliest available is {base}")]
26    Gap { requested: u64, base: u64 },
27
28    /// The consumer has reached the end of the stream and has shut down gracefully.
29    #[error("consumer reached end of stream")]
30    EndOfStream,
31}
32
33impl From<anyhow::Error> for ConsumerError {
34    fn from(err: anyhow::Error) -> Self {
35        // By default, we'll treat any generic error as a connection-level, retryable error.
36        ConsumerError::Connection(err)
37    }
38}
39
40impl From<anyhow::Error> for ProcessingError {
41    fn from(err: anyhow::Error) -> Self {
42        // Default to Retryable for generic errors. Callers should use
43        // ProcessingError::NonRetryable directly for known permanent failures.
44        ProcessingError::Retryable(err)
45    }
46}