Skip to main content

rocketmq_error/unified/
protocol.rs

1// Copyright 2023 The RocketMQ Rust Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! RocketMQ protocol-specific errors
16
17use thiserror::Error;
18
19/// Protocol validation and processing errors
20#[derive(Debug, Error)]
21pub enum ProtocolError {
22    /// Invalid command code
23    #[error("Invalid command code: {code}")]
24    InvalidCommand { code: i32 },
25
26    /// Unsupported protocol version
27    #[error("Unsupported protocol version: {version}")]
28    UnsupportedVersion { version: i32 },
29
30    /// Required header field is missing
31    #[error("Missing required header field: {field}")]
32    HeaderMissing { field: &'static str },
33
34    /// Required body is missing
35    #[error("Missing required message body")]
36    BodyMissing,
37
38    /// Checksum mismatch
39    #[error("Checksum mismatch: expected {expected:x}, got {actual:x}")]
40    ChecksumMismatch { expected: u32, actual: u32 },
41
42    /// Invalid message format
43    #[error("Invalid message format: {reason}")]
44    InvalidMessage { reason: String },
45
46    /// Protocol decode error
47    #[error("Protocol decode error: ext_fields_length={ext_fields_len}, header_length={header_len}")]
48    DecodeError { ext_fields_len: usize, header_len: usize },
49
50    /// Unsupported serialization type
51    #[error("Unsupported serialization type: {serialize_type}")]
52    UnsupportedSerializationType { serialize_type: u8 },
53}
54
55impl ProtocolError {
56    /// Create an invalid command error
57    #[inline]
58    pub fn invalid_command(code: i32) -> Self {
59        Self::InvalidCommand { code }
60    }
61
62    /// Create a header missing error
63    #[inline]
64    pub fn header_missing(field: &'static str) -> Self {
65        Self::HeaderMissing { field }
66    }
67
68    /// Create a checksum mismatch error
69    #[inline]
70    pub fn checksum_mismatch(expected: u32, actual: u32) -> Self {
71        Self::ChecksumMismatch { expected, actual }
72    }
73
74    /// Create an invalid message error
75    #[inline]
76    pub fn invalid_message(reason: impl Into<String>) -> Self {
77        Self::InvalidMessage { reason: reason.into() }
78    }
79}
80
81#[cfg(test)]
82mod tests {
83    use super::*;
84
85    #[test]
86    fn test_protocol_error() {
87        let err = ProtocolError::invalid_command(999);
88        assert_eq!(err.to_string(), "Invalid command code: 999");
89
90        let err = ProtocolError::UnsupportedVersion { version: 1 };
91        assert_eq!(err.to_string(), "Unsupported protocol version: 1");
92
93        let err = ProtocolError::header_missing("topic");
94        assert_eq!(err.to_string(), "Missing required header field: topic");
95
96        let err = ProtocolError::BodyMissing;
97        assert_eq!(err.to_string(), "Missing required message body");
98
99        let err = ProtocolError::checksum_mismatch(0xABCD, 0x1234);
100        assert!(err.to_string().contains("abcd"));
101        assert!(err.to_string().contains("1234"));
102
103        let err = ProtocolError::invalid_message("too long");
104        assert_eq!(err.to_string(), "Invalid message format: too long");
105
106        let err = ProtocolError::DecodeError {
107            ext_fields_len: 10,
108            header_len: 20,
109        };
110        assert_eq!(
111            err.to_string(),
112            "Protocol decode error: ext_fields_length=10, header_length=20"
113        );
114
115        let err = ProtocolError::UnsupportedSerializationType { serialize_type: 2 };
116        assert_eq!(err.to_string(), "Unsupported serialization type: 2");
117    }
118}