Skip to content

test: BadNamespaceError race condition during integration test teardown #915

Description

@PythonFZ

Problem

Integration tests that use real uvicorn servers (via the server_factory fixture) occasionally produce a BadNamespaceError during teardown:

zndraw_socketio/wrapper.py, line 1332, in emit
    self._sio.emit(event_name, payload, **kwargs)
socketio/client.py, line 223, in emit
    raise exceptions.BadNamespaceError(
socketio.exceptions.BadNamespaceError: / is not a connected namespace.

The error doesn't fail tests (exit code 0), but it pollutes stderr and masks real issues.

Root cause

Race condition between client disconnect and server shutdown during test cleanup:

  1. Test ends → clients call disconnect()on_disconnect handler fires in src/zndraw/socketio.py
  2. Handler tries to emit SessionLeft, LockUpdate, and GeometryInvalidate events (lines 129-149)
  3. Concurrently, server_factory fixture cleanup sets server.should_exit = True (conftest.py:290)
  4. The uvicorn server closes the socketio namespace / before the emits complete
  5. BadNamespaceError is raised

In production

This race condition is test-specific — in production, server shutdown and client disconnect don't happen simultaneously. However, the on_disconnect handler lacks error handling for the case where the namespace is gone, which could theoretically affect graceful server shutdown scenarios.

Possible fixes

  1. Wrap emits in on_disconnect with try/except for BadNamespaceError — log and continue
  2. Add a grace period in server_factory cleanup — sleep briefly between should_exit = True and thread.join() to let in-flight handlers complete
  3. Check namespace connectivity before emitting in the disconnect handler

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions