indexbus_typed/
errors.rs

1use indexbus_core::{PublishWithError, RecvWithError};
2
3/// Typed-layer error.
4///
5/// This wraps and normalizes errors from:
6/// - `indexbus-core` (queue and routing semantics)
7/// - `indexbus-msg` (v1 envelope/header)
8/// - `indexbus-codec` (payload encoding/decoding)
9///
10/// ## Recovery guidance
11///
12/// - [`Error::TooLarge`] is a producer-side sizing issue: the encoded payload does not fit in a
13///   single slot.
14/// - [`Error::UnsupportedCodec`] / `*Mismatch` errors typically indicate a schema mismatch
15///   between producer and consumer (wrong expected type or version).
16/// - [`Error::Envelope`] / [`Error::Codec`] are data validation failures. In receive paths, the
17///   underlying message is still consumed (see `indexbus-core` `try_recv_with` semantics).
18#[derive(Debug, Clone, PartialEq, Eq)]
19pub enum Error {
20    /// Payload cannot fit into a single slot.
21    TooLarge {
22        /// Maximum supported payload size in bytes.
23        max: usize,
24        /// Actual payload size in bytes.
25        len: usize,
26    },
27    /// Error raised by the core region handles.
28    Core(indexbus_core::Error),
29    /// Error raised while encoding/decoding the v1 header/envelope.
30    Envelope(indexbus_msg::Error),
31    /// Error raised by the configured codec.
32    Codec(indexbus_codec::CodecError),
33    /// The received message uses a codec id that does not match `C::CODEC_ID`.
34    UnsupportedCodec {
35        /// Codec id found in the message header.
36        codec_id: u8,
37    },
38    /// `schema_id` does not match the expected message identity.
39    SchemaMismatch {
40        /// Expected schema id.
41        expected: u64,
42        /// Schema id found in the header.
43        found: u64,
44    },
45    /// `msg_type` does not match the expected message identity.
46    TypeMismatch {
47        /// Expected message type.
48        expected: u32,
49        /// Message type found in the header.
50        found: u32,
51    },
52    /// `msg_version` does not match the expected message identity.
53    VersionMismatch {
54        /// Expected message version.
55        expected: u16,
56        /// Message version found in the header.
57        found: u16,
58    },
59}
60
61impl From<indexbus_core::Error> for Error {
62    fn from(value: indexbus_core::Error) -> Self {
63        match value {
64            indexbus_core::Error::TooLarge { max, len } => Self::TooLarge { max, len },
65            other => Self::Core(other),
66        }
67    }
68}
69
70impl From<indexbus_msg::Error> for Error {
71    fn from(value: indexbus_msg::Error) -> Self {
72        Self::Envelope(value)
73    }
74}
75
76impl From<indexbus_codec::CodecError> for Error {
77    fn from(value: indexbus_codec::CodecError) -> Self {
78        Self::Codec(value)
79    }
80}
81
82impl<E> From<PublishWithError<E>> for Error
83where
84    E: Into<Error>,
85{
86    fn from(value: PublishWithError<E>) -> Self {
87        match value {
88            PublishWithError::Core(e) => e.into(),
89            PublishWithError::Encode(e) => e.into(),
90        }
91    }
92}
93
94impl<E> From<RecvWithError<E>> for Error
95where
96    E: Into<Error>,
97{
98    fn from(value: RecvWithError<E>) -> Self {
99        match value {
100            RecvWithError::Core(e) => e.into(),
101            RecvWithError::Decode(e) => e.into(),
102        }
103    }
104}
105
106#[cfg(feature = "std")]
107impl std::fmt::Display for Error {
108    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
109        match self {
110            Self::TooLarge { max, len } => write!(f, "too large: max {max}, len {len}"),
111            Self::Core(e) => write!(f, "core error: {e:?}"),
112            Self::Envelope(e) => write!(f, "envelope error: {e:?}"),
113            Self::Codec(e) => write!(f, "codec error: {e:?}"),
114            Self::UnsupportedCodec { codec_id } => write!(f, "unsupported codec_id: {codec_id}"),
115            Self::SchemaMismatch { expected, found } => {
116                write!(f, "schema_id mismatch: expected {expected}, found {found}")
117            }
118            Self::TypeMismatch { expected, found } => {
119                write!(f, "msg_type mismatch: expected {expected}, found {found}")
120            }
121            Self::VersionMismatch { expected, found } => {
122                write!(
123                    f,
124                    "msg_version mismatch: expected {expected}, found {found}"
125                )
126            }
127        }
128    }
129}
130
131#[cfg(feature = "std")]
132impl std::error::Error for Error {}