fix: resolve WebSocket crashes from websockets 16.0 incompatibility (#97)

The /ws redirect handler crashed with AttributeError because websockets
16.0 removed the legacy transfer_data_task attribute. The /swarm/live
endpoint could also error on early client disconnects during accept.

Co-authored-by: Alexander Payne <apayne@MM.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Alexander Whitestone
2026-02-28 20:09:03 -05:00
committed by GitHub
parent b7c89d1101
commit d4acaefee9
2 changed files with 14 additions and 2 deletions

View File

@@ -545,9 +545,17 @@ async def ws_redirect(websocket: WebSocket):
an endpoint. Stale browser tabs retry forever, spamming 403 errors.
Accept the connection and immediately close with a policy-violation
code so the client stops retrying.
websockets 16.0 dropped the legacy ``transfer_data_task`` attribute,
so calling ``websocket.close()`` after accept triggers an
AttributeError. Use the raw ASGI send instead.
"""
await websocket.accept()
await websocket.close(code=1008, reason="Use /swarm/live instead")
try:
await websocket.close(code=1008, reason="Use /swarm/live instead")
except AttributeError:
# websockets >= 16.0 — close via raw ASGI message
await websocket.send({"type": "websocket.close", "code": 1008})
@app.get("/", response_class=HTMLResponse)

View File

@@ -409,7 +409,11 @@ def submit_bid(bid: BidRequest):
@router.websocket("/live")
async def swarm_live(websocket: WebSocket):
"""WebSocket endpoint for live swarm event streaming."""
await ws_manager.connect(websocket)
try:
await ws_manager.connect(websocket)
except Exception as exc:
logger.warning("WebSocket accept failed: %s", exc)
return
try:
while True:
data = await websocket.receive_text()