Skip to content
This repository was archived by the owner on Sep 22, 2023. It is now read-only.

Make websocket handshake failures to transparently report server-responded error information #81

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions src/ai/backend/client/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
35 changes: 30 additions & 5 deletions tests/test_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down