rama_ws/protocol/
error.rs1use crate::protocol::{frame::coding::OpCodeData, message::Message};
2use rama_core::error::OpaqueError;
3use rama_net::conn::is_connection_error;
4use rama_utils::str::utf8;
5use std::{error, fmt, io};
6
7#[derive(Debug)]
9pub enum ProtocolError {
10 Utf8(OpaqueError),
12 Io(io::Error),
17 InvalidOpcode(u8),
19 InvalidCloseSequence,
21 MessageTooLong {
25 size: usize,
27 max_size: usize,
29 },
30 UnmaskedFrameFromClient,
32 WriteBufferFull(Message),
34 SendAfterClosing,
36 ReceivedAfterClosing,
38 NonZeroReservedBits,
40 MaskedFrameFromServer,
42 FragmentedControlFrame,
44 ControlFrameTooBig,
46 UnknownControlFrameType(u8),
48 ResetWithoutClosingHandshake,
50 UnexpectedContinueFrame,
52 ExpectedFragment(OpCodeData),
54 UnknownDataFrameType(u8),
56 DeflateError(OpaqueError),
58}
59
60impl ProtocolError {
61 pub fn is_connection_error(&self) -> bool {
64 if let Self::Io(err) = self {
65 is_connection_error(err)
66 } else {
67 false
68 }
69 }
70}
71
72impl From<utf8::DecodeError<'_>> for ProtocolError {
73 fn from(value: utf8::DecodeError<'_>) -> Self {
74 Self::Utf8(OpaqueError::from_display(value.to_string()))
75 }
76}
77
78impl From<std::str::Utf8Error> for ProtocolError {
79 fn from(value: std::str::Utf8Error) -> Self {
80 Self::Utf8(OpaqueError::from_std(value))
81 }
82}
83
84impl From<io::Error> for ProtocolError {
85 fn from(value: io::Error) -> Self {
86 Self::Io(value)
87 }
88}
89
90impl fmt::Display for ProtocolError {
91 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92 match self {
93 Self::Utf8(err) => write!(f, "UTF-8 error: {err:?}"),
94 Self::Io(err) => write!(f, "I/O error: {err:?}"),
95 Self::InvalidOpcode(code) => write!(f, "Encountered invalid opcode: {code}"),
96 Self::InvalidCloseSequence => write!(f, "Invalid close sequence"),
97 Self::MessageTooLong { size, max_size } => {
98 write!(f, "Message too long: {size} > {max_size}")
99 }
100 Self::UnmaskedFrameFromClient => {
101 write!(f, "Received an unmasked frame from client")
102 }
103 Self::WriteBufferFull(_) => write!(f, "Write buffer is full"),
104 Self::SendAfterClosing => {
105 write!(f, "Sending after closing is not allowed")
106 }
107 Self::ReceivedAfterClosing => {
108 write!(f, "Remote sent after having closed")
109 }
110 Self::NonZeroReservedBits => {
111 write!(f, "Reserved bits are non-zero")
112 }
113 Self::MaskedFrameFromServer => {
114 write!(f, "Received a masked frame from server")
115 }
116 Self::FragmentedControlFrame => {
117 write!(f, "Fragmented control frame")
118 }
119 Self::ControlFrameTooBig => {
120 write!(
121 f,
122 "Control frame too big (payload must be 125 bytes or less)"
123 )
124 }
125 Self::UnknownControlFrameType(t) => {
126 write!(f, "Unknown control frame type: {t}")
127 }
128 Self::ResetWithoutClosingHandshake => {
129 write!(f, "Connection reset without closing handshake")
130 }
131 Self::UnexpectedContinueFrame => {
132 write!(f, "Continue frame but nothing to continue")
133 }
134 Self::ExpectedFragment(data) => {
135 write!(f, "While waiting for more fragments received: {data}")
136 }
137 Self::UnknownDataFrameType(t) => {
138 write!(f, "Unknown data frame type: {t}")
139 }
140 Self::DeflateError(err) => write!(f, "Deflate error: {err:?}"),
141 }
142 }
143}
144
145impl error::Error for ProtocolError {
146 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
147 match self {
148 Self::Utf8(err) => Some(err as &(dyn error::Error + 'static)),
149 Self::Io(err) => Some(err as &(dyn std::error::Error + 'static)),
150 Self::InvalidOpcode(_)
151 | Self::InvalidCloseSequence
152 | Self::MessageTooLong { .. }
153 | Self::UnmaskedFrameFromClient
154 | Self::WriteBufferFull(_)
155 | Self::SendAfterClosing
156 | Self::ReceivedAfterClosing
157 | Self::NonZeroReservedBits
158 | Self::MaskedFrameFromServer
159 | Self::FragmentedControlFrame
160 | Self::ControlFrameTooBig
161 | Self::UnknownControlFrameType(_)
162 | Self::ResetWithoutClosingHandshake
163 | Self::UnexpectedContinueFrame
164 | Self::ExpectedFragment(_)
165 | Self::UnknownDataFrameType(_) => None,
166 Self::DeflateError(err) => Some(err as &(dyn std::error::Error + 'static)),
167 }
168 }
169}