hive_btle/
error.rs

1//! Error types for HIVE-BTLE
2//!
3//! Provides a comprehensive error enum for all BLE operations including
4//! adapter initialization, discovery, GATT operations, and connectivity.
5
6#[cfg(not(feature = "std"))]
7use alloc::string::String;
8#[cfg(not(feature = "std"))]
9use core::fmt;
10
11/// Result type alias for BLE operations
12pub type Result<T> = core::result::Result<T, BleError>;
13
14/// Errors that can occur during BLE operations
15#[derive(Debug)]
16#[cfg_attr(feature = "std", derive(thiserror::Error))]
17pub enum BleError {
18    /// Bluetooth adapter not available on this device
19    #[cfg_attr(feature = "std", error("Bluetooth adapter not available"))]
20    AdapterNotAvailable,
21
22    /// Bluetooth is powered off
23    #[cfg_attr(feature = "std", error("Bluetooth is powered off"))]
24    NotPowered,
25
26    /// Bluetooth permissions not granted
27    #[cfg_attr(feature = "std", error("Bluetooth permissions not granted: {0}"))]
28    PermissionDenied(String),
29
30    /// Feature not supported by this adapter or platform
31    #[cfg_attr(feature = "std", error("Feature not supported: {0}"))]
32    NotSupported(String),
33
34    /// Connection to peer failed
35    #[cfg_attr(feature = "std", error("Connection failed: {0}"))]
36    ConnectionFailed(String),
37
38    /// Connection was lost
39    #[cfg_attr(feature = "std", error("Connection lost: {0}"))]
40    ConnectionLost(String),
41
42    /// Discovery operation failed
43    #[cfg_attr(feature = "std", error("Discovery failed: {0}"))]
44    DiscoveryFailed(String),
45
46    /// GATT operation failed
47    #[cfg_attr(feature = "std", error("GATT error: {0}"))]
48    GattError(String),
49
50    /// Characteristic not found
51    #[cfg_attr(feature = "std", error("Characteristic not found: {0}"))]
52    CharacteristicNotFound(String),
53
54    /// Service not found
55    #[cfg_attr(feature = "std", error("Service not found: {0}"))]
56    ServiceNotFound(String),
57
58    /// MTU negotiation failed
59    #[cfg_attr(
60        feature = "std",
61        error("MTU negotiation failed: requested {requested}, got {actual}")
62    )]
63    MtuNegotiationFailed {
64        /// Requested MTU size
65        requested: u16,
66        /// Actual negotiated MTU
67        actual: u16,
68    },
69
70    /// Security/pairing error
71    #[cfg_attr(feature = "std", error("Security error: {0}"))]
72    SecurityError(String),
73
74    /// Pairing failed
75    #[cfg_attr(feature = "std", error("Pairing failed: {0}"))]
76    PairingFailed(String),
77
78    /// Sync operation failed
79    #[cfg_attr(feature = "std", error("Sync error: {0}"))]
80    SyncError(String),
81
82    /// Platform-specific error
83    #[cfg_attr(feature = "std", error("Platform error: {0}"))]
84    PlatformError(String),
85
86    /// Operation timed out
87    #[cfg_attr(feature = "std", error("Operation timed out"))]
88    Timeout,
89
90    /// Invalid configuration
91    #[cfg_attr(feature = "std", error("Invalid configuration: {0}"))]
92    InvalidConfig(String),
93
94    /// Invalid state for this operation
95    #[cfg_attr(feature = "std", error("Invalid state: {0}"))]
96    InvalidState(String),
97
98    /// Resource exhausted (e.g., max connections reached)
99    #[cfg_attr(feature = "std", error("Resource exhausted: {0}"))]
100    ResourceExhausted(String),
101
102    /// I/O error
103    #[cfg_attr(feature = "std", error("I/O error: {0}"))]
104    Io(String),
105}
106
107// Manual Display implementation for no_std
108#[cfg(not(feature = "std"))]
109impl fmt::Display for BleError {
110    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111        match self {
112            BleError::AdapterNotAvailable => write!(f, "Bluetooth adapter not available"),
113            BleError::NotPowered => write!(f, "Bluetooth is powered off"),
114            BleError::PermissionDenied(msg) => write!(f, "Permission denied: {}", msg),
115            BleError::NotSupported(msg) => write!(f, "Not supported: {}", msg),
116            BleError::ConnectionFailed(msg) => write!(f, "Connection failed: {}", msg),
117            BleError::ConnectionLost(msg) => write!(f, "Connection lost: {}", msg),
118            BleError::DiscoveryFailed(msg) => write!(f, "Discovery failed: {}", msg),
119            BleError::GattError(msg) => write!(f, "GATT error: {}", msg),
120            BleError::CharacteristicNotFound(uuid) => {
121                write!(f, "Characteristic not found: {}", uuid)
122            }
123            BleError::ServiceNotFound(uuid) => write!(f, "Service not found: {}", uuid),
124            BleError::MtuNegotiationFailed { requested, actual } => {
125                write!(
126                    f,
127                    "MTU negotiation failed: requested {}, got {}",
128                    requested, actual
129                )
130            }
131            BleError::SecurityError(msg) => write!(f, "Security error: {}", msg),
132            BleError::PairingFailed(msg) => write!(f, "Pairing failed: {}", msg),
133            BleError::SyncError(msg) => write!(f, "Sync error: {}", msg),
134            BleError::PlatformError(msg) => write!(f, "Platform error: {}", msg),
135            BleError::Timeout => write!(f, "Operation timed out"),
136            BleError::InvalidConfig(msg) => write!(f, "Invalid config: {}", msg),
137            BleError::InvalidState(msg) => write!(f, "Invalid state: {}", msg),
138            BleError::ResourceExhausted(msg) => write!(f, "Resource exhausted: {}", msg),
139            BleError::Io(msg) => write!(f, "I/O error: {}", msg),
140        }
141    }
142}
143
144#[cfg(feature = "std")]
145impl From<std::io::Error> for BleError {
146    fn from(err: std::io::Error) -> Self {
147        BleError::Io(err.to_string())
148    }
149}
150
151#[cfg(test)]
152mod tests {
153    use super::*;
154
155    #[test]
156    fn test_error_display() {
157        let err = BleError::ConnectionFailed("peer unreachable".to_string());
158        assert!(err.to_string().contains("Connection failed"));
159        assert!(err.to_string().contains("peer unreachable"));
160    }
161
162    #[test]
163    fn test_mtu_error() {
164        let err = BleError::MtuNegotiationFailed {
165            requested: 512,
166            actual: 23,
167        };
168        let msg = err.to_string();
169        assert!(msg.contains("512"));
170        assert!(msg.contains("23"));
171    }
172}