Merge pull request #1278 from ashleysommer/graceful_cancel

Gracefully handle when the request_handler_task is cancelled.
This commit is contained in:
Eli Uriegas
2018-08-17 11:41:39 -07:00
committed by GitHub
2 changed files with 54 additions and 7 deletions

View File

@@ -571,6 +571,10 @@ class Sanic:
:return: Nothing
"""
# Define `response` var here to remove warnings about
# allocation before assignment below.
response = None
cancelled = False
try:
# -------------------------------------------- #
# Request Middleware
@@ -597,6 +601,13 @@ class Sanic:
response = handler(request, *args, **kwargs)
if isawaitable(response):
response = await response
except CancelledError:
# If response handler times out, the server handles the error
# and cancels the handle_request job.
# In this case, the transport is already closed and we cannot
# issue a response.
response = None
cancelled = True
except Exception as e:
# -------------------------------------------- #
# Response Generation Failed
@@ -622,13 +633,22 @@ class Sanic:
# -------------------------------------------- #
# Response Middleware
# -------------------------------------------- #
try:
response = await self._run_response_middleware(request,
response)
except BaseException:
error_logger.exception(
'Exception occurred in one of response middleware handlers'
)
# Don't run response middleware if response is None
if response is not None:
try:
response = await self._run_response_middleware(request,
response)
except CancelledError:
# Response middleware can timeout too, as above.
response = None
cancelled = True
except BaseException:
error_logger.exception(
'Exception occurred in one of response '
'middleware handlers'
)
if cancelled:
raise CancelledError()
# pass the response to the correct callback
if isinstance(response, StreamingHTTPResponse):