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:
- Test ends → clients call
disconnect() → on_disconnect handler fires in src/zndraw/socketio.py
- Handler tries to emit
SessionLeft, LockUpdate, and GeometryInvalidate events (lines 129-149)
- Concurrently,
server_factory fixture cleanup sets server.should_exit = True (conftest.py:290)
- The uvicorn server closes the socketio namespace
/ before the emits complete
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
- Wrap emits in
on_disconnect with try/except for BadNamespaceError — log and continue
- Add a grace period in
server_factory cleanup — sleep briefly between should_exit = True and thread.join() to let in-flight handlers complete
- Check namespace connectivity before emitting in the disconnect handler
🤖 Generated with Claude Code
Problem
Integration tests that use real uvicorn servers (via the
server_factoryfixture) occasionally produce aBadNamespaceErrorduring teardown: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:
disconnect()→on_disconnecthandler fires insrc/zndraw/socketio.pySessionLeft,LockUpdate, andGeometryInvalidateevents (lines 129-149)server_factoryfixture cleanup setsserver.should_exit = True(conftest.py:290)/before the emits completeBadNamespaceErroris raisedIn production
This race condition is test-specific — in production, server shutdown and client disconnect don't happen simultaneously. However, the
on_disconnecthandler lacks error handling for the case where the namespace is gone, which could theoretically affect graceful server shutdown scenarios.Possible fixes
on_disconnectwith try/except forBadNamespaceError— log and continueserver_factorycleanup — sleep briefly betweenshould_exit = Trueandthread.join()to let in-flight handlers complete🤖 Generated with Claude Code