Skip to content

Connection handlers can be called multiple times with different signatures #1490

@rgov

Description

@rgov

A pattern that appears in the codebase is to try calling a (dis)connection handler with one set of arguments, and if it raises a TypeError, call again with a different set:

try:
success = self._trigger_event(
'connect', namespace, sid, self.environ[eio_sid])
except TypeError:
success = self._trigger_event(
'connect', namespace, sid, self.environ[eio_sid], None)

This is risky if the event handler itself can raise a TypeError, unrelated to the handler's arity. This could cause the handler to be run up to the point it throws a TypeError, then the TypeError is consumed and the handler is called again.

A contrived example might be:

@sio.on('connect', namespace='*')
async def on_client_connect(namespace, sid, environ, *args):
    initialize_client_state(sid)
    2 + "two"

This will be called once with (namespace, sid, environ) and initialize some client state. Then it will raise a TypeError, so it will be called again with (namespace, sid, environ, auth). The client state will be initialized a second time, which might lead to an unexpected state, resource leaks, etc.

It may be better to check inspect.signature(handler).parameters -- however when the event is triggered with self._trigger_event() it doesn't have a reference to the handler callable.

(I'm filing this only because while debugging some other part of my application, I kept getting complaints about including auth or not including auth in my parameter list. Finally I settled on adding *args and moving on.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions