Merge pull request 'fix: WebSocket crash from websockets 16.0 + branch pruning' (#2) from claude/consolidated-cherry-picks into main
Reviewed-on: http://localhost:3000/rockachopa/Timmy-time-dashboard/pulls/2
This commit was merged in pull request #2.
This commit is contained in:
@@ -410,11 +410,17 @@ app.include_router(cascade_router)
|
||||
|
||||
@app.websocket("/ws")
|
||||
async def ws_redirect(websocket: WebSocket):
|
||||
"""Catch stale /ws connections and close cleanly."""
|
||||
"""Catch stale /ws connections and close cleanly.
|
||||
|
||||
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()
|
||||
try:
|
||||
await websocket.close(code=1008, reason="Deprecated endpoint")
|
||||
except AttributeError:
|
||||
# websockets >= 16.0 — close via raw ASGI message
|
||||
await websocket.send({"type": "websocket.close", "code": 1008})
|
||||
|
||||
|
||||
|
||||
23
src/integrations/chat_bridge/vendors/discord.py
vendored
23
src/integrations/chat_bridge/vendors/discord.py
vendored
@@ -297,7 +297,21 @@ class DiscordVendor(ChatPlatform):
|
||||
logger.error("Failed to save Discord token: %s", exc)
|
||||
|
||||
def load_token(self) -> str | None:
|
||||
"""Load token from state file or config."""
|
||||
"""Load token from config or state file.
|
||||
|
||||
Priority: settings.discord_token (env/.env) > state file.
|
||||
The state file is a fallback for tokens set via the /discord/setup UI.
|
||||
"""
|
||||
# 1. Config / env var takes priority
|
||||
try:
|
||||
from config import settings
|
||||
|
||||
if settings.discord_token:
|
||||
return settings.discord_token
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 2. Fall back to state file (set via /discord/setup endpoint)
|
||||
try:
|
||||
if _STATE_FILE.exists():
|
||||
data = json.loads(_STATE_FILE.read_text())
|
||||
@@ -307,12 +321,7 @@ class DiscordVendor(ChatPlatform):
|
||||
except Exception as exc:
|
||||
logger.debug("Could not read discord state file: %s", exc)
|
||||
|
||||
try:
|
||||
from config import settings
|
||||
|
||||
return settings.discord_token or None
|
||||
except Exception:
|
||||
return None
|
||||
return None
|
||||
|
||||
# ── OAuth2 URL generation ──────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -34,11 +34,14 @@ class TestDiscordVendor:
|
||||
assert status.guild_count == 0
|
||||
|
||||
def test_save_and_load_token(self, tmp_path, monkeypatch):
|
||||
from config import settings
|
||||
from integrations.chat_bridge.vendors import discord as discord_mod
|
||||
from integrations.chat_bridge.vendors.discord import DiscordVendor
|
||||
|
||||
state_file = tmp_path / "discord_state.json"
|
||||
monkeypatch.setattr(discord_mod, "_STATE_FILE", state_file)
|
||||
# Settings token empty — so state file token is used as fallback
|
||||
monkeypatch.setattr(settings, "discord_token", "")
|
||||
|
||||
vendor = DiscordVendor()
|
||||
vendor.save_token("test-token-abc")
|
||||
|
||||
Reference in New Issue
Block a user