19
19
cast ,
20
20
)
21
21
22
- from ..exceptions import ConnectionClosed , ConnectionClosedOK , ProtocolError
22
+ from ..exceptions import (
23
+ ConcurrencyError ,
24
+ ConnectionClosed ,
25
+ ConnectionClosedOK ,
26
+ ProtocolError ,
27
+ )
23
28
from ..frames import DATA_OPCODES , BytesLike , CloseCode , Frame , Opcode
24
29
from ..http11 import Request , Response
25
30
from ..protocol import CLOSED , OPEN , Event , Protocol , State
@@ -262,16 +267,16 @@ async def recv(self, decode: bool | None = None) -> Data:
262
267
263
268
Raises:
264
269
ConnectionClosed: When the connection is closed.
265
- RuntimeError : If two coroutines call :meth:`recv` or
270
+ ConcurrencyError : If two coroutines call :meth:`recv` or
266
271
:meth:`recv_streaming` concurrently.
267
272
268
273
"""
269
274
try :
270
275
return await self .recv_messages .get (decode )
271
276
except EOFError :
272
277
raise self .protocol .close_exc from self .recv_exc
273
- except RuntimeError :
274
- raise RuntimeError (
278
+ except ConcurrencyError :
279
+ raise ConcurrencyError (
275
280
"cannot call recv while another coroutine "
276
281
"is already running recv or recv_streaming"
277
282
) from None
@@ -283,8 +288,9 @@ async def recv_streaming(self, decode: bool | None = None) -> AsyncIterator[Data
283
288
This method is designed for receiving fragmented messages. It returns an
284
289
asynchronous iterator that yields each fragment as it is received. This
285
290
iterator must be fully consumed. Else, future calls to :meth:`recv` or
286
- :meth:`recv_streaming` will raise :exc:`RuntimeError`, making the
287
- connection unusable.
291
+ :meth:`recv_streaming` will raise
292
+ :exc:`~websockets.exceptions.ConcurrencyError`, making the connection
293
+ unusable.
288
294
289
295
:meth:`recv_streaming` raises the same exceptions as :meth:`recv`.
290
296
@@ -315,7 +321,7 @@ async def recv_streaming(self, decode: bool | None = None) -> AsyncIterator[Data
315
321
316
322
Raises:
317
323
ConnectionClosed: When the connection is closed.
318
- RuntimeError : If two coroutines call :meth:`recv` or
324
+ ConcurrencyError : If two coroutines call :meth:`recv` or
319
325
:meth:`recv_streaming` concurrently.
320
326
321
327
"""
@@ -324,8 +330,8 @@ async def recv_streaming(self, decode: bool | None = None) -> AsyncIterator[Data
324
330
yield frame
325
331
except EOFError :
326
332
raise self .protocol .close_exc from self .recv_exc
327
- except RuntimeError :
328
- raise RuntimeError (
333
+ except ConcurrencyError :
334
+ raise ConcurrencyError (
329
335
"cannot call recv_streaming while another coroutine "
330
336
"is already running recv or recv_streaming"
331
337
) from None
@@ -593,7 +599,7 @@ async def ping(self, data: Data | None = None) -> Awaitable[float]:
593
599
594
600
Raises:
595
601
ConnectionClosed: When the connection is closed.
596
- RuntimeError : If another ping was sent with the same data and
602
+ ConcurrencyError : If another ping was sent with the same data and
597
603
the corresponding pong wasn't received yet.
598
604
599
605
"""
@@ -607,7 +613,7 @@ async def ping(self, data: Data | None = None) -> Awaitable[float]:
607
613
async with self .send_context ():
608
614
# Protect against duplicates if a payload is explicitly set.
609
615
if data in self .pong_waiters :
610
- raise RuntimeError ("already waiting for a pong with the same data" )
616
+ raise ConcurrencyError ("already waiting for a pong with the same data" )
611
617
612
618
# Generate a unique random payload otherwise.
613
619
while data is None or data in self .pong_waiters :
@@ -793,7 +799,7 @@ async def send_context(
793
799
# Let the caller interact with the protocol.
794
800
try :
795
801
yield
796
- except (ProtocolError , RuntimeError ):
802
+ except (ProtocolError , ConcurrencyError ):
797
803
# The protocol state wasn't changed. Exit immediately.
798
804
raise
799
805
except Exception as exc :
@@ -1092,15 +1098,17 @@ def broadcast(
1092
1098
if raise_exceptions :
1093
1099
if sys .version_info [:2 ] < (3 , 11 ): # pragma: no cover
1094
1100
raise ValueError ("raise_exceptions requires at least Python 3.11" )
1095
- exceptions = []
1101
+ exceptions : list [ Exception ] = []
1096
1102
1097
1103
for connection in connections :
1104
+ exception : Exception
1105
+
1098
1106
if connection .protocol .state is not OPEN :
1099
1107
continue
1100
1108
1101
1109
if connection .fragmented_send_waiter is not None :
1102
1110
if raise_exceptions :
1103
- exception = RuntimeError ("sending a fragmented message" )
1111
+ exception = ConcurrencyError ("sending a fragmented message" )
1104
1112
exceptions .append (exception )
1105
1113
else :
1106
1114
connection .logger .warning (
0 commit comments