specter/websocket/
error.rs1use std::io;
2
3pub type WebSocketResult<T> = std::result::Result<T, WebSocketError>;
4
5#[derive(Debug, thiserror::Error)]
6pub enum WebSocketError {
7 #[error("WebSocket handshake failed for {url}: expected status 101, got {status}")]
8 InvalidStatus { url: String, status: u16 },
9
10 #[error("WebSocket handshake failed for {url}: invalid Sec-WebSocket-Accept")]
11 InvalidAccept { url: String },
12
13 #[error("WebSocket handshake failed for {url}: unexpected subprotocol")]
14 UnexpectedSubprotocol { url: String },
15
16 #[error("WebSocket handshake failed for {url}: unexpected extension")]
17 UnexpectedExtension { url: String },
18
19 #[error("WebSocket protocol error for {url}: {message}")]
20 Protocol { url: String, message: String },
21
22 #[error("WebSocket UTF-8 error for {url}: {message}")]
23 Utf8 { url: String, message: String },
24
25 #[error("WebSocket size limit exceeded for {url}: {message}")]
26 LimitExceeded { url: String, message: String },
27
28 #[error("WebSocket connection closed for {url}")]
29 ConnectionClosed { url: String },
30
31 #[error("WebSocket timeout for {url}: {operation}")]
32 Timeout { url: String, operation: String },
33
34 #[error("WebSocket I/O error for {url}: {source}")]
35 Io {
36 url: String,
37 #[source]
38 source: io::Error,
39 },
40
41 #[error("WebSocket URL error: {0}")]
42 Url(String),
43}
44
45impl WebSocketError {
46 #[cold]
47 #[inline(never)]
48 pub(crate) fn protocol(url: &crate::url::Url, message: impl Into<String>) -> Self {
49 Self::Protocol {
50 url: url.to_string(),
51 message: message.into(),
52 }
53 }
54
55 #[cold]
56 #[inline(never)]
57 pub(crate) fn utf8(url: &crate::url::Url, message: impl Into<String>) -> Self {
58 Self::Utf8 {
59 url: url.to_string(),
60 message: message.into(),
61 }
62 }
63
64 #[cold]
65 #[inline(never)]
66 pub(crate) fn limit_exceeded(url: &crate::url::Url, message: impl Into<String>) -> Self {
67 Self::LimitExceeded {
68 url: url.to_string(),
69 message: message.into(),
70 }
71 }
72
73 #[cold]
74 #[inline(never)]
75 pub(crate) fn connection_closed(url: &crate::url::Url) -> Self {
76 Self::ConnectionClosed {
77 url: url.to_string(),
78 }
79 }
80
81 #[cold]
82 #[inline(never)]
83 pub(crate) fn io(url: &crate::url::Url, source: io::Error) -> Self {
84 Self::Io {
85 url: url.to_string(),
86 source,
87 }
88 }
89
90 pub(crate) fn close_code(&self) -> Option<crate::websocket::CloseCode> {
91 match self {
92 Self::Protocol { .. } => Some(crate::websocket::CloseCode::Protocol),
93 Self::Utf8 { .. } => Some(crate::websocket::CloseCode::Invalid),
94 Self::LimitExceeded { .. } => Some(crate::websocket::CloseCode::Size),
95 _ => None,
96 }
97 }
98}
99
100impl From<crate::url::ParseError> for WebSocketError {
101 fn from(err: crate::url::ParseError) -> Self {
102 Self::Url(err.to_string())
103 }
104}