Skip to main content

rocketmq_error/
controller_error.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//! Controller module error types
16//!
17//! This module provides error types specific to the RocketMQ controller subsystem,
18//! which manages broker lifecycles, master elections, and cluster coordination.
19
20use std::io;
21
22use thiserror::Error;
23
24/// Controller module error types
25///
26/// Errors that can occur during controller operations including:
27/// - Raft consensus failures
28/// - Leadership transitions
29/// - Broker registration and metadata management
30/// - Network and serialization issues
31#[derive(Debug, Error)]
32pub enum ControllerError {
33    /// IO errors
34    #[error("IO error: {0}")]
35    Io(#[from] io::Error),
36
37    /// Raft consensus errors
38    #[error("Raft error: {0}")]
39    Raft(String),
40
41    /// Not the leader error
42    #[error("Not leader, current leader is: {}", leader_id.map(|id| id.to_string()).unwrap_or_else(|| "unknown".to_string()))]
43    NotLeader { leader_id: Option<u64> },
44
45    /// Metadata not found
46    #[error("Metadata not found: {key}")]
47    MetadataNotFound { key: String },
48
49    /// Invalid request
50    #[error("Invalid request: {0}")]
51    InvalidRequest(String),
52
53    /// Broker registration error
54    #[error("Broker registration failed: {0}")]
55    BrokerRegistrationFailed(String),
56
57    /// Not initialized error
58    #[error("Not initialized: {0}")]
59    NotInitialized(String),
60
61    /// Initialization failed error
62    #[error("Initialization failed")]
63    InitializationFailed,
64
65    /// Configuration error
66    #[error("Configuration error: {0}")]
67    ConfigError(String),
68
69    /// Serialization error
70    #[error("Serialization error: {0}")]
71    SerializationError(String),
72
73    /// Storage error
74    #[error("Storage error: {0}")]
75    StorageError(String),
76
77    /// Network error
78    #[error("Network error: {0}")]
79    NetworkError(String),
80
81    /// Timeout error
82    #[error("Operation timeout after {timeout_ms}ms")]
83    Timeout { timeout_ms: u64 },
84
85    /// Internal error
86    #[error("Internal error: {0}")]
87    Internal(String),
88
89    /// Shutdown error
90    #[error("Controller is shutting down")]
91    Shutdown,
92}
93
94/// Result type alias for Controller operations
95pub type ControllerResult<T> = std::result::Result<T, ControllerError>;
96
97#[cfg(test)]
98mod tests {
99    use super::*;
100
101    #[test]
102    fn test_controller_error() {
103        let err = ControllerError::Io(io::Error::other("test"));
104        assert_eq!(err.to_string(), "IO error: test");
105
106        let err = ControllerError::Raft("raft error".to_string());
107        assert_eq!(err.to_string(), "Raft error: raft error");
108
109        let err = ControllerError::NotLeader { leader_id: Some(1) };
110        assert_eq!(err.to_string(), "Not leader, current leader is: 1");
111
112        let err = ControllerError::NotLeader { leader_id: None };
113        assert_eq!(err.to_string(), "Not leader, current leader is: unknown");
114
115        let err = ControllerError::MetadataNotFound {
116            key: "broker-a".to_string(),
117        };
118        assert_eq!(err.to_string(), "Metadata not found: broker-a");
119
120        let err = ControllerError::InvalidRequest("bad request".to_string());
121        assert_eq!(err.to_string(), "Invalid request: bad request");
122
123        let err = ControllerError::BrokerRegistrationFailed("failed".to_string());
124        assert_eq!(err.to_string(), "Broker registration failed: failed");
125
126        let err = ControllerError::NotInitialized("init first".to_string());
127        assert_eq!(err.to_string(), "Not initialized: init first");
128
129        let err = ControllerError::InitializationFailed;
130        assert_eq!(err.to_string(), "Initialization failed");
131
132        let err = ControllerError::ConfigError("invalid config".to_string());
133        assert_eq!(err.to_string(), "Configuration error: invalid config");
134
135        let err = ControllerError::SerializationError("serde error".to_string());
136        assert_eq!(err.to_string(), "Serialization error: serde error");
137
138        let err = ControllerError::StorageError("disk full".to_string());
139        assert_eq!(err.to_string(), "Storage error: disk full");
140
141        let err = ControllerError::NetworkError("disconnected".to_string());
142        assert_eq!(err.to_string(), "Network error: disconnected");
143
144        let err = ControllerError::Timeout { timeout_ms: 5000 };
145        assert_eq!(err.to_string(), "Operation timeout after 5000ms");
146
147        let err = ControllerError::Internal("panic".to_string());
148        assert_eq!(err.to_string(), "Internal error: panic");
149
150        let err = ControllerError::Shutdown;
151        assert_eq!(err.to_string(), "Controller is shutting down");
152    }
153}