fix(signalr): add exception handler (sentry-14,26,32,36)
This commit is contained in:
@@ -77,9 +77,13 @@ class Client:
|
|||||||
await asyncio.sleep(settings.signalr_ping_interval)
|
await asyncio.sleep(settings.signalr_ping_interval)
|
||||||
except WebSocketDisconnect:
|
except WebSocketDisconnect:
|
||||||
break
|
break
|
||||||
except Exception as e:
|
except RuntimeError as e:
|
||||||
logger.error(f"Error in ping task for {self.connection_id}: {e}")
|
if "disconnect message" in str(e):
|
||||||
break
|
break
|
||||||
|
else:
|
||||||
|
logger.error(f"Error in ping task for {self.connection_id}: {e}")
|
||||||
|
except Exception:
|
||||||
|
logger.exception(f"Error in client {self.connection_id}")
|
||||||
|
|
||||||
|
|
||||||
class Hub[TState: UserState]:
|
class Hub[TState: UserState]:
|
||||||
@@ -158,6 +162,8 @@ class Hub[TState: UserState]:
|
|||||||
return client
|
return client
|
||||||
|
|
||||||
async def remove_client(self, client: Client) -> None:
|
async def remove_client(self, client: Client) -> None:
|
||||||
|
if client.connection_token not in self.clients:
|
||||||
|
return
|
||||||
del self.clients[client.connection_token]
|
del self.clients[client.connection_token]
|
||||||
if client._listen_task:
|
if client._listen_task:
|
||||||
client._listen_task.cancel()
|
client._listen_task.cancel()
|
||||||
@@ -186,7 +192,22 @@ class Hub[TState: UserState]:
|
|||||||
await method(client)
|
await method(client)
|
||||||
|
|
||||||
async def send_packet(self, client: Client, packet: Packet) -> None:
|
async def send_packet(self, client: Client, packet: Packet) -> None:
|
||||||
await client.send_packet(packet)
|
try:
|
||||||
|
await client.send_packet(packet)
|
||||||
|
except WebSocketDisconnect as e:
|
||||||
|
logger.info(
|
||||||
|
f"Client {client.connection_id} disconnected: {e.code}, {e.reason}"
|
||||||
|
)
|
||||||
|
await self.remove_client(client)
|
||||||
|
except RuntimeError as e:
|
||||||
|
if "disconnect message" in str(e):
|
||||||
|
logger.info(f"Client {client.connection_id} closed the connection.")
|
||||||
|
else:
|
||||||
|
logger.exception(f"RuntimeError in client {client.connection_id}: {e}")
|
||||||
|
await self.remove_client(client)
|
||||||
|
except Exception:
|
||||||
|
logger.exception(f"Error in client {client.connection_id}")
|
||||||
|
await self.remove_client(client)
|
||||||
|
|
||||||
async def broadcast_call(self, method: str, *args: Any) -> None:
|
async def broadcast_call(self, method: str, *args: Any) -> None:
|
||||||
tasks = []
|
tasks = []
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ from app.database.score_token import ScoreToken
|
|||||||
from app.dependencies.database import engine
|
from app.dependencies.database import engine
|
||||||
from app.dependencies.fetcher import get_fetcher
|
from app.dependencies.fetcher import get_fetcher
|
||||||
from app.dependencies.storage import get_storage_service
|
from app.dependencies.storage import get_storage_service
|
||||||
|
from app.exception import InvokeException
|
||||||
from app.models.mods import mods_to_int
|
from app.models.mods import mods_to_int
|
||||||
from app.models.score import LegacyReplaySoloScoreInfo, ScoreStatistics
|
from app.models.score import LegacyReplaySoloScoreInfo, ScoreStatistics
|
||||||
from app.models.spectator_hub import (
|
from app.models.spectator_hub import (
|
||||||
@@ -30,6 +31,7 @@ from app.utils import unix_timestamp_to_windows
|
|||||||
|
|
||||||
from .hub import Client, Hub
|
from .hub import Client, Hub
|
||||||
|
|
||||||
|
from httpx import HTTPError
|
||||||
from sqlalchemy.orm import joinedload
|
from sqlalchemy.orm import joinedload
|
||||||
from sqlmodel import select
|
from sqlmodel import select
|
||||||
from sqlmodel.ext.asyncio.session import AsyncSession
|
from sqlmodel.ext.asyncio.session import AsyncSession
|
||||||
@@ -190,9 +192,12 @@ class SpectatorHub(Hub[StoreClientState]):
|
|||||||
fetcher = await get_fetcher()
|
fetcher = await get_fetcher()
|
||||||
async with AsyncSession(engine) as session:
|
async with AsyncSession(engine) as session:
|
||||||
async with session.begin():
|
async with session.begin():
|
||||||
beatmap = await Beatmap.get_or_fetch(
|
try:
|
||||||
session, fetcher, bid=state.beatmap_id
|
beatmap = await Beatmap.get_or_fetch(
|
||||||
)
|
session, fetcher, bid=state.beatmap_id
|
||||||
|
)
|
||||||
|
except HTTPError:
|
||||||
|
raise InvokeException(f"Beatmap {state.beatmap_id} not found.")
|
||||||
user = (
|
user = (
|
||||||
await session.exec(select(User).where(User.id == user_id))
|
await session.exec(select(User).where(User.id == user_id))
|
||||||
).first()
|
).first()
|
||||||
|
|||||||
Reference in New Issue
Block a user