1use std::net::IpAddr;
7
8#[derive(Debug, thiserror::Error)]
10pub enum BrokerError {
11 #[error("Registry error: {0}")]
12 Registry(#[from] RegistryError),
13
14 #[error("Subscription error: {0}")]
15 Subscription(#[from] SubscriptionError),
16
17 #[error("Polling error: {0}")]
18 Polling(#[from] PollingError),
19
20 #[error("Event processing error: {0}")]
21 EventProcessing(String),
22
23 #[error("Callback server error: {0}")]
24 CallbackServer(String),
25
26 #[error("Configuration error: {0}")]
27 Configuration(String),
28
29 #[error("Firewall detection error: {0}")]
30 FirewallDetection(String),
31
32 #[error("IO error: {0}")]
33 Io(#[from] std::io::Error),
34
35 #[error("Serialization error: {0}")]
36 Serialization(#[from] serde_json::Error),
37}
38
39#[derive(Debug, thiserror::Error)]
41pub enum RegistryError {
42 #[error("Speaker/service pair already registered: {speaker_ip} {service:?}")]
43 DuplicateRegistration {
44 speaker_ip: IpAddr,
45 service: sonos_api::Service,
46 },
47
48 #[error("Registration not found: {0}")]
49 NotFound(crate::RegistrationId),
50
51 #[error("Invalid speaker IP address: {0}")]
52 InvalidIpAddress(String),
53
54 #[error("Registry is full (max registrations: {max_registrations})")]
55 RegistryFull { max_registrations: usize },
56}
57
58#[derive(Debug, thiserror::Error)]
60pub enum SubscriptionError {
61 #[error("Subscription expired")]
62 Expired,
63
64 #[error("Subscription failed to create: {0}")]
65 CreationFailed(String),
66
67 #[error("Subscription renewal failed: {0}")]
68 RenewalFailed(String),
69
70 #[error("Network error: {0}")]
71 NetworkError(String),
72
73 #[error("UPnP service error: {0}")]
74 ServiceError(String),
75
76 #[error("Callback registration failed: {0}")]
77 CallbackRegistration(String),
78
79 #[error("Invalid subscription state")]
80 InvalidState,
81}
82
83#[derive(Debug, thiserror::Error)]
85pub enum PollingError {
86 #[error("Network error during polling: {0}")]
87 Network(String),
88
89 #[error("State parsing error: {0}")]
90 StateParsing(String),
91
92 #[error("Service not supported for polling: {service:?}")]
93 UnsupportedService { service: sonos_api::Service },
94
95 #[error("Device unreachable: {device_ip}")]
96 DeviceUnreachable { device_ip: IpAddr },
97
98 #[error("Polling task spawn failed: {0}")]
99 TaskSpawn(String),
100
101 #[error("Too many consecutive errors: {error_count}")]
102 TooManyErrors { error_count: u32 },
103
104 #[error("SOAP client error: {0}")]
105 SoapClient(String),
106}
107
108#[derive(Debug, thiserror::Error)]
110pub enum EventProcessingError {
111 #[error("Event parsing failed: {0}")]
112 Parsing(String),
113
114 #[error("Event enrichment failed: {0}")]
115 Enrichment(String),
116
117 #[error("Channel closed")]
118 ChannelClosed,
119
120 #[error("Timeout waiting for event")]
121 Timeout,
122
123 #[error("Iterator already consumed")]
124 IteratorConsumed,
125}
126
127pub type BrokerResult<T> = Result<T, BrokerError>;
129
130pub type RegistryResult<T> = Result<T, RegistryError>;
132
133pub type SubscriptionResult<T> = Result<T, SubscriptionError>;
135
136pub type PollingResult<T> = Result<T, PollingError>;
138
139pub type EventProcessingResult<T> = Result<T, EventProcessingError>;
141
142#[cfg(test)]
143mod tests {
144 use std::error::Error;
145
146 use super::*;
147
148 #[test]
149 fn test_error_display() {
150 let err = BrokerError::Configuration("test error".to_string());
151 assert!(err.to_string().contains("Configuration error"));
152
153 let registry_err = RegistryError::DuplicateRegistration {
154 speaker_ip: "192.168.1.100".parse().unwrap(),
155 service: sonos_api::Service::AVTransport,
156 };
157 assert!(registry_err.to_string().contains("already registered"));
158 }
159
160 #[test]
161 fn test_error_chaining() {
162 let registry_err = RegistryError::NotFound(crate::RegistrationId::new(1));
163 let broker_err = BrokerError::Registry(registry_err);
164
165 assert!(broker_err.to_string().contains("Registry error"));
166 assert!(broker_err.source().is_some());
167 }
168}