diff --git a/src/ai/backend/client/request.py b/src/ai/backend/client/request.py index 79db3380..bbaf3625 100644 --- a/src/ai/backend/client/request.py +++ b/src/ai/backend/client/request.py @@ -584,14 +584,18 @@ async def __aenter__(self): msg = 'Request to the API endpoint has failed.\n' \ 'Check your network connection and/or the server status.\n' \ 'Error detail: {!r}'.format(e) - raise BackendClientError(msg) from e + raise BackendClientError(msg) else: self.session.config.rotate_endpoints() continue except aiohttp.ClientResponseError as e: - msg = 'API endpoint response error.\n' \ - '\u279c {!r}'.format(e) - raise BackendClientError(msg) from e + # msg = await e.read() + # FIXME: update after upstream patch + msg = '''{ + "type": "https://api.backend.ai/probs/generic-error", + "title": "aiohttp patch required to get the original response body" + }''' + raise BackendAPIError(e.status, e.message, msg) else: break diff --git a/tests/test_request.py b/tests/test_request.py index 4d4b2b12..27f57dfa 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -181,10 +181,36 @@ def test_invalid_requests(dummy_endpoint): with pytest.raises(BackendAPIError) as e: with rqst.fetch(): pass - assert e.status == 404 - assert e.data['type'] == \ - 'https://api.backend.ai/probs/kernel-not-found' - assert e.data['title'] == 'Kernel Not Found' + assert e.value.status == 404 + assert e.value.data['type'] == \ + 'https://api.backend.ai/probs/kernel-not-found' + assert e.value.data['title'] == 'Kernel Not Found' + + +@pytest.mark.asyncio +async def test_invalid_websocket_request(dummy_endpoint): + with aioresponses() as m: + async with AsyncSession() as session: + body = json.dumps({ + 'type': 'https://api.backend.ai/probs/kernel-not-found', + 'title': 'Kernel Not Found', + }).encode('utf8') + m.get( + dummy_endpoint, status=404, body=body, + headers={'Content-Type': 'application/problem+json; charset=utf-8', + 'Content-Length': str(len(body))}, + ) + rqst = Request(session, 'GET', '/') + with pytest.raises(BackendAPIError) as e: + async with rqst.connect_websocket(): + pass + assert e.value.status == 404 + assert e.value.reason == 'Invalid response status' # set by aiohttp + assert e.value.data['title'].startswith('aiohttp patch required') + # FIXME: update after upstream patch + # assert e.value.data['type'] == \ + # 'https://api.backend.ai/probs/kernel-not-found' + # assert e.value.data['title'] == 'Kernel Not Found' @pytest.mark.asyncio @@ -208,7 +234,6 @@ async def test_fetch_client_error_async(dummy_endpoint): pass -@pytest.mark.xfail @pytest.mark.asyncio async def test_fetch_cancellation_async(dummy_endpoint): # It seems that aiohttp swallows asyncio.CancelledError