diff --git a/src/socketio/async_client.py b/src/socketio/async_client.py index 53c669b..a4f4267 100644 --- a/src/socketio/async_client.py +++ b/src/socketio/async_client.py @@ -175,7 +175,7 @@ class AsyncClient(base_client.BaseClient): if set(self.namespaces) != set(self.connection_namespaces): await self.disconnect() raise exceptions.ConnectionError( - 'One or more namespaces failed to connect' + 'One or more namespaces failed to connect: ' + ', '.join(self.failed_namespaces)) self.connected = True diff --git a/src/socketio/client.py b/src/socketio/client.py index 4fc36f4..bf1bee4 100644 --- a/src/socketio/client.py +++ b/src/socketio/client.py @@ -168,7 +168,7 @@ class Client(base_client.BaseClient): if set(self.namespaces) != set(self.connection_namespaces): self.disconnect() raise exceptions.ConnectionError( - 'One or more namespaces failed to connect: ' + 'One or more namespaces failed to connect: ' + ', '.join(self.failed_namespaces)) self.connected = True diff --git a/tests/async/test_client.py b/tests/async/test_client.py index d7e0f9e..b4b0c6c 100644 --- a/tests/async/test_client.py +++ b/tests/async/test_client.py @@ -203,6 +203,60 @@ class TestAsyncClient: assert c.connected is True assert c.namespaces == {'/bar': '123', '/foo': '456'} + async def test_connect_wait_one_namespaces_error(self): + c = async_client.AsyncClient() + c.eio.connect = mock.AsyncMock() + c._connect_event = mock.MagicMock() + + async def mock_connect(): + if c.failed_namespaces == []: + c.failed_namespaces = ['/foo'] + return True + return False + + c._connect_event.wait = mock_connect + with pytest.raises(exceptions.ConnectionError, + match='failed to connect: /foo'): + await c.connect( + 'url', + namespaces=['/foo'], + wait=True, + wait_timeout=0.01, + ) + assert c.connected is False + assert c.namespaces == {} + assert c.failed_namespaces == ['/foo'] + + async def test_connect_wait_three_namespaces_error(self): + c = async_client.AsyncClient() + c.eio.connect = mock.AsyncMock() + c._connect_event = mock.MagicMock() + + async def mock_connect(): + if c.namespaces == {}: + c.namespaces = {'/bar': '123'} + return True + elif c.namespaces == {'/bar': '123'} and c.failed_namespaces == []: + c.failed_namespaces = ['/baz'] + return True + elif c.failed_namespaces == ['/baz']: + c.failed_namespaces = ['/baz', '/foo'] + return True + return False + + c._connect_event.wait = mock_connect + with pytest.raises(exceptions.ConnectionError, + match='failed to connect: /baz, /foo'): + await c.connect( + 'url', + namespaces=['/foo', '/bar', '/baz'], + wait=True, + wait_timeout=0.01, + ) + assert c.connected is False + assert c.namespaces == {'/bar': '123'} + assert c.failed_namespaces == ['/baz', '/foo'] + async def test_connect_timeout(self): c = async_client.AsyncClient() c.eio.connect = mock.AsyncMock() diff --git a/tests/common/test_client.py b/tests/common/test_client.py index 7ee2bac..cbda3f1 100644 --- a/tests/common/test_client.py +++ b/tests/common/test_client.py @@ -350,6 +350,62 @@ class TestClient: assert c.connected is True assert c.namespaces == {'/bar': '123', '/foo': '456'} + def test_connect_wait_one_namespaces_error(self): + c = client.Client() + c.eio.connect = mock.MagicMock() + c._connect_event = mock.MagicMock() + + def mock_connect(timeout): + assert timeout == 0.01 + if c.failed_namespaces == []: + c.failed_namespaces = ['/foo'] + return True + return False + + c._connect_event.wait = mock_connect + with pytest.raises(exceptions.ConnectionError, + match='failed to connect: /foo'): + c.connect( + 'url', + namespaces=['/foo'], + wait=True, + wait_timeout=0.01, + ) + assert c.connected is False + assert c.namespaces == {} + assert c.failed_namespaces == ['/foo'] + + def test_connect_wait_three_namespaces_error(self): + c = client.Client() + c.eio.connect = mock.MagicMock() + c._connect_event = mock.MagicMock() + + def mock_connect(timeout): + assert timeout == 0.01 + if c.namespaces == {}: + c.namespaces = {'/bar': '123'} + return True + elif c.namespaces == {'/bar': '123'} and c.failed_namespaces == []: + c.failed_namespaces = ['/baz'] + return True + elif c.failed_namespaces == ['/baz']: + c.failed_namespaces = ['/baz', '/foo'] + return True + return False + + c._connect_event.wait = mock_connect + with pytest.raises(exceptions.ConnectionError, + match='failed to connect: /baz, /foo'): + c.connect( + 'url', + namespaces=['/foo', '/bar', '/baz'], + wait=True, + wait_timeout=0.01, + ) + assert c.connected is False + assert c.namespaces == {'/bar': '123'} + assert c.failed_namespaces == ['/baz', '/foo'] + def test_connect_timeout(self): c = client.Client() c.eio.connect = mock.MagicMock()