Skip to main content

rustapi_ws/
error.rs

1//! WebSocket error types
2
3use std::fmt;
4
5/// Error type for WebSocket operations
6#[derive(Debug)]
7pub enum WebSocketError {
8    /// Invalid WebSocket upgrade request
9    InvalidUpgrade(String),
10    /// WebSocket handshake failed
11    HandshakeFailed(String),
12    /// Connection closed unexpectedly
13    ConnectionClosed,
14    /// Failed to send message
15    SendFailed(String),
16    /// Failed to receive message
17    ReceiveFailed(String),
18    /// Message serialization error
19    SerializationError(String),
20    /// Message deserialization error
21    DeserializationError(String),
22    /// Protocol error
23    ProtocolError(String),
24    /// IO error
25    IoError(std::io::Error),
26    /// Tungstenite error
27    Tungstenite(tungstenite::Error),
28}
29
30impl fmt::Display for WebSocketError {
31    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32        match self {
33            Self::InvalidUpgrade(msg) => write!(f, "Invalid WebSocket upgrade request: {}", msg),
34            Self::HandshakeFailed(msg) => write!(f, "WebSocket handshake failed: {}", msg),
35            Self::ConnectionClosed => write!(f, "Connection closed unexpectedly"),
36            Self::SendFailed(msg) => write!(f, "Failed to send message: {}", msg),
37            Self::ReceiveFailed(msg) => write!(f, "Failed to receive message: {}", msg),
38            Self::SerializationError(msg) => write!(f, "Message serialization error: {}", msg),
39            Self::DeserializationError(msg) => write!(f, "Message deserialization error: {}", msg),
40            Self::ProtocolError(msg) => write!(f, "WebSocket protocol error: {}", msg),
41            Self::IoError(e) => write!(f, "IO error: {}", e),
42            Self::Tungstenite(e) => write!(f, "WebSocket error: {}", e),
43        }
44    }
45}
46
47impl std::error::Error for WebSocketError {
48    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
49        match self {
50            Self::IoError(e) => Some(e),
51            Self::Tungstenite(e) => Some(e),
52            _ => None,
53        }
54    }
55}
56
57impl From<std::io::Error> for WebSocketError {
58    fn from(e: std::io::Error) -> Self {
59        Self::IoError(e)
60    }
61}
62
63impl From<tungstenite::Error> for WebSocketError {
64    fn from(e: tungstenite::Error) -> Self {
65        Self::Tungstenite(e)
66    }
67}
68
69impl WebSocketError {
70    /// Create an invalid upgrade error
71    pub fn invalid_upgrade(msg: impl Into<String>) -> Self {
72        Self::InvalidUpgrade(msg.into())
73    }
74
75    /// Create a handshake failed error
76    pub fn handshake_failed(msg: impl Into<String>) -> Self {
77        Self::HandshakeFailed(msg.into())
78    }
79
80    /// Create a send failed error
81    pub fn send_failed(msg: impl Into<String>) -> Self {
82        Self::SendFailed(msg.into())
83    }
84
85    /// Create a receive failed error
86    pub fn receive_failed(msg: impl Into<String>) -> Self {
87        Self::ReceiveFailed(msg.into())
88    }
89
90    /// Create a serialization error
91    pub fn serialization_error(msg: impl Into<String>) -> Self {
92        Self::SerializationError(msg.into())
93    }
94
95    /// Create a deserialization error
96    pub fn deserialization_error(msg: impl Into<String>) -> Self {
97        Self::DeserializationError(msg.into())
98    }
99
100    /// Create a protocol error
101    pub fn protocol_error(msg: impl Into<String>) -> Self {
102        Self::ProtocolError(msg.into())
103    }
104}
105
106impl From<WebSocketError> for rustapi_core::ApiError {
107    fn from(err: WebSocketError) -> Self {
108        match err {
109            WebSocketError::InvalidUpgrade(msg) => {
110                rustapi_core::ApiError::bad_request(format!("WebSocket upgrade failed: {}", msg))
111            }
112            WebSocketError::HandshakeFailed(msg) => {
113                rustapi_core::ApiError::bad_request(format!("WebSocket handshake failed: {}", msg))
114            }
115            _ => rustapi_core::ApiError::internal(err.to_string()),
116        }
117    }
118}
119
120impl From<crate::auth::AuthError> for rustapi_core::ApiError {
121    fn from(err: crate::auth::AuthError) -> Self {
122        match err {
123            crate::auth::AuthError::TokenMissing => {
124                rustapi_core::ApiError::unauthorized("Authentication token missing")
125            }
126            crate::auth::AuthError::TokenExpired => {
127                rustapi_core::ApiError::unauthorized("Token has expired")
128            }
129            crate::auth::AuthError::InvalidSignature => {
130                rustapi_core::ApiError::unauthorized("Invalid token signature")
131            }
132            crate::auth::AuthError::InvalidFormat(msg) => {
133                rustapi_core::ApiError::bad_request(format!("Invalid token format: {}", msg))
134            }
135            crate::auth::AuthError::ValidationFailed(msg) => {
136                rustapi_core::ApiError::unauthorized(format!("Token validation failed: {}", msg))
137            }
138            crate::auth::AuthError::InsufficientPermissions(msg) => {
139                rustapi_core::ApiError::forbidden(format!("Insufficient permissions: {}", msg))
140            }
141        }
142    }
143}