Skip to content

Commit d47b3f1

Browse files
authored
catch exception on socketio connection (#1365)
* catch exception on sockteio connection
1 parent 38f9c66 commit d47b3f1

File tree

2 files changed

+35
-10
lines changed

2 files changed

+35
-10
lines changed

services/web/server/src/simcore_service_webserver/socketio/handlers.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,23 @@
1111
from typing import Dict, List, Optional
1212

1313
from aiohttp import web
14-
from socketio.exceptions import ConnectionRefusedError as socket_io_connection_error
1514

1615
from servicelib.observer import observe
1716
from servicelib.utils import fire_and_forget_task, logged_gather
17+
from socketio.exceptions import ConnectionRefusedError as SocketIOConnectionError
1818

1919
from ..login.decorators import RQT_USERID_KEY, login_required
2020
from ..resource_manager.websocket_manager import managed_resource
2121
from .config import get_socket_server
22+
from .handlers_utils import register_socketio_handler
2223

2324
ANONYMOUS_USER_ID = -1
2425
_SOCKET_IO_AIOHTTP_REQUEST_KEY = "aiohttp.request"
2526

2627
log = logging.getLogger(__file__)
2728

2829

30+
@register_socketio_handler
2931
async def connect(sid: str, environ: Dict, app: web.Application) -> bool:
3032
"""socketio reserved handler for when the fontend connects through socket.io
3133
@@ -42,7 +44,9 @@ async def connect(sid: str, environ: Dict, app: web.Application) -> bool:
4244
try:
4345
await authenticate_user(sid, app, request)
4446
except web.HTTPUnauthorized:
45-
raise socket_io_connection_error("authentification failed")
47+
raise SocketIOConnectionError("authentification failed")
48+
except Exception as exc: # pylint: disable=broad-except
49+
raise SocketIOConnectionError(f"Unexpected error: {exc}")
4650

4751
return True
4852

@@ -107,6 +111,7 @@ async def user_logged_out(
107111
fire_and_forget_task(disconnect_other_sockets(sio, sockets))
108112

109113

114+
@register_socketio_handler
110115
async def disconnect(sid: str, app: web.Application) -> None:
111116
"""socketio reserved handler for when the socket.io connection is disconnected.
112117

services/web/server/src/simcore_service_webserver/socketio/handlers_utils.py

+28-8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
from .config import APP_CLIENT_SOCKET_DECORATED_HANDLERS_KEY, get_socket_server
88

99

10+
socketio_handlers_registry = []
11+
12+
1013
def socket_io_handler(app: web.Application):
1114
"""this decorator allows passing additional paramters to python-socketio compatible handlers.
1215
I.e. python-socketio handler expect functions of type `async def function(sid, *args, **kwargs)`
@@ -18,6 +21,7 @@ def decorator(func):
1821
async def wrapped(*args, **kwargs):
1922
return await func(*args, **kwargs, app=app)
2023

24+
2125
return wrapped
2226

2327
return decorator
@@ -33,18 +37,34 @@ def has_socket_io_handler_signature(fun) -> bool:
3337

3438
def register_handlers(app: web.Application, module: ModuleType):
3539
sio = get_socket_server(app)
36-
predicate = (
37-
lambda obj: inspect.isfunction(obj)
38-
and has_socket_io_handler_signature(obj)
39-
and inspect.iscoroutinefunction(obj)
40-
and inspect.getmodule(obj) == module
41-
)
42-
member_fcts = inspect.getmembers(module, predicate)
40+
member_fcts = [
41+
fct for fct in socketio_handlers_registry if inspect.getmodule(fct) == module
42+
]
4343
# convert handler
4444
partial_fcts = [
45-
socket_io_handler(app)(func_handler) for _, func_handler in member_fcts
45+
socket_io_handler(app)(func_handler) for func_handler in member_fcts
4646
]
4747
app[APP_CLIENT_SOCKET_DECORATED_HANDLERS_KEY] = partial_fcts
4848
# register the fcts
4949
for func in partial_fcts:
5050
sio.on(func.__name__, handler=func)
51+
52+
53+
def register_socketio_handler(func: callable) -> callable:
54+
"""this decorator appends handlers to a registry if they fit certain rules
55+
56+
:param func: the function to call
57+
:type func: callable
58+
:return: the function to call
59+
:rtype: callable
60+
"""
61+
is_handler = (
62+
inspect.isfunction(func)
63+
and has_socket_io_handler_signature(func)
64+
and inspect.iscoroutinefunction(func)
65+
)
66+
if is_handler:
67+
socketio_handlers_registry.append(func)
68+
else:
69+
raise SyntaxError("the function shall be of type fct(*args, app: web.Application")
70+
return func

0 commit comments

Comments
 (0)