1use thiserror::Error;
4
5#[derive(Error, Debug)]
7pub enum WebSocketError {
8 #[error("Invalid WebSocket upgrade request: {0}")]
10 InvalidUpgrade(String),
11
12 #[error("WebSocket handshake failed: {0}")]
14 HandshakeFailed(String),
15
16 #[error("Connection closed unexpectedly")]
18 ConnectionClosed,
19
20 #[error("Failed to send message: {0}")]
22 SendFailed(String),
23
24 #[error("Failed to receive message: {0}")]
26 ReceiveFailed(String),
27
28 #[error("Message serialization error: {0}")]
30 SerializationError(String),
31
32 #[error("Message deserialization error: {0}")]
34 DeserializationError(String),
35
36 #[error("WebSocket protocol error: {0}")]
38 ProtocolError(String),
39
40 #[error("IO error: {0}")]
42 IoError(#[from] std::io::Error),
43
44 #[error("WebSocket error: {0}")]
46 Tungstenite(#[from] tungstenite::Error),
47}
48
49impl WebSocketError {
50 pub fn invalid_upgrade(msg: impl Into<String>) -> Self {
52 Self::InvalidUpgrade(msg.into())
53 }
54
55 pub fn handshake_failed(msg: impl Into<String>) -> Self {
57 Self::HandshakeFailed(msg.into())
58 }
59
60 pub fn send_failed(msg: impl Into<String>) -> Self {
62 Self::SendFailed(msg.into())
63 }
64
65 pub fn receive_failed(msg: impl Into<String>) -> Self {
67 Self::ReceiveFailed(msg.into())
68 }
69
70 pub fn serialization_error(msg: impl Into<String>) -> Self {
72 Self::SerializationError(msg.into())
73 }
74
75 pub fn deserialization_error(msg: impl Into<String>) -> Self {
77 Self::DeserializationError(msg.into())
78 }
79
80 pub fn protocol_error(msg: impl Into<String>) -> Self {
82 Self::ProtocolError(msg.into())
83 }
84}
85
86impl From<WebSocketError> for rustapi_core::ApiError {
87 fn from(err: WebSocketError) -> Self {
88 match err {
89 WebSocketError::InvalidUpgrade(msg) => {
90 rustapi_core::ApiError::bad_request(format!("WebSocket upgrade failed: {}", msg))
91 }
92 WebSocketError::HandshakeFailed(msg) => {
93 rustapi_core::ApiError::bad_request(format!("WebSocket handshake failed: {}", msg))
94 }
95 _ => rustapi_core::ApiError::internal(err.to_string()),
96 }
97 }
98}
99
100impl From<crate::auth::AuthError> for rustapi_core::ApiError {
101 fn from(err: crate::auth::AuthError) -> Self {
102 match err {
103 crate::auth::AuthError::TokenMissing => {
104 rustapi_core::ApiError::unauthorized("Authentication token missing")
105 }
106 crate::auth::AuthError::TokenExpired => {
107 rustapi_core::ApiError::unauthorized("Token has expired")
108 }
109 crate::auth::AuthError::InvalidSignature => {
110 rustapi_core::ApiError::unauthorized("Invalid token signature")
111 }
112 crate::auth::AuthError::InvalidFormat(msg) => {
113 rustapi_core::ApiError::bad_request(format!("Invalid token format: {}", msg))
114 }
115 crate::auth::AuthError::ValidationFailed(msg) => {
116 rustapi_core::ApiError::unauthorized(format!("Token validation failed: {}", msg))
117 }
118 crate::auth::AuthError::InsufficientPermissions(msg) => {
119 rustapi_core::ApiError::forbidden(format!("Insufficient permissions: {}", msg))
120 }
121 }
122 }
123}