Middleware and error handling refactoring.
This commit is contained in:
parent
d2d6008eec
commit
17d100400f
32
sanic/app.py
32
sanic/app.py
|
@ -955,22 +955,22 @@ class Sanic:
|
|||
response = HTTPResponse(
|
||||
"An error occurred while handling an error", status=500
|
||||
)
|
||||
# Run response middleware
|
||||
if response is not None:
|
||||
try:
|
||||
response = await self._run_response_middleware(
|
||||
request, response, request_name=request.name
|
||||
response = await request.respond(response)
|
||||
except:
|
||||
# Skip response middleware
|
||||
request.stream.respond(response)
|
||||
await response.send(end_stream=True)
|
||||
raise
|
||||
else:
|
||||
response = request.stream.response
|
||||
if isinstance(response, BaseHTTPResponse):
|
||||
await response.send(end_stream=True)
|
||||
else:
|
||||
raise ServerError(
|
||||
f"Invalid response type {response!r} (need HTTPResponse)"
|
||||
)
|
||||
except CancelledError:
|
||||
# FIXME: Ensure exiting in a clean manner instead of this
|
||||
# and verify py37 and py38 test_middleware.py separately
|
||||
request.stream.keep_alive = False
|
||||
except Exception:
|
||||
error_logger.exception(
|
||||
"Exception occurred in one of response "
|
||||
"middleware handlers"
|
||||
)
|
||||
return response
|
||||
|
||||
async def handle_request(self, request):
|
||||
"""Take a request from the HTTP Server and return a response object
|
||||
|
@ -1039,6 +1039,8 @@ class Sanic:
|
|||
response = await response
|
||||
if response:
|
||||
response = await request.respond(response)
|
||||
else:
|
||||
response = request.stream.response
|
||||
# Make sure that response is finished / run StreamingHTTP callback
|
||||
if isinstance(response, BaseHTTPResponse):
|
||||
await response.send(end_stream=True)
|
||||
|
@ -1053,9 +1055,7 @@ class Sanic:
|
|||
# -------------------------------------------- #
|
||||
# Response Generation Failed
|
||||
# -------------------------------------------- #
|
||||
response = await self.handle_exception(request, e)
|
||||
response = await request.respond(response)
|
||||
await response.send(end_stream=True)
|
||||
await self.handle_exception(request, e)
|
||||
|
||||
# -------------------------------------------------------------------- #
|
||||
# Testing
|
||||
|
|
|
@ -274,9 +274,26 @@ class Http:
|
|||
# From request and handler states we can respond, otherwise be silent
|
||||
if self.stage is Stage.HANDLER:
|
||||
app = self.protocol.app
|
||||
if self.request is None:
|
||||
self.create_empty_request()
|
||||
response = await app.handle_exception(self.request, exception)
|
||||
await self.respond(response).send(end_stream=True)
|
||||
|
||||
def create_empty_request(self):
|
||||
"""Current error handling code needs a request object that won't exist
|
||||
if an error occurred during before a request was received. Create a
|
||||
bogus response for error handling use."""
|
||||
# FIXME: Avoid this by refactoring error handling and response code
|
||||
self.request = self.protocol.request_class(
|
||||
url_bytes=self.url.encode() if self.url else b"*",
|
||||
headers=Header({}),
|
||||
version="1.1",
|
||||
method="NONE",
|
||||
transport=self.protocol.transport,
|
||||
app=self.protocol.app,
|
||||
)
|
||||
self.request.stream = self
|
||||
|
||||
def log_response(self):
|
||||
"""
|
||||
Helper method provided to enable the logging of responses in case if
|
||||
|
|
|
@ -137,6 +137,12 @@ class HttpProtocol(asyncio.Protocol):
|
|||
except Exception:
|
||||
logger.exception("protocol.connection_task uncaught")
|
||||
finally:
|
||||
if self._debug and self._http and self._http.request:
|
||||
ip = self.transport.get_extra_info("peername")
|
||||
logger.error(
|
||||
"Connection lost before response written"
|
||||
f" @ {ip} {self._http.request}"
|
||||
)
|
||||
self._http = None
|
||||
self._task = None
|
||||
try:
|
||||
|
@ -229,9 +235,6 @@ class HttpProtocol(asyncio.Protocol):
|
|||
self.resume_writing()
|
||||
if self._task:
|
||||
self._task.cancel()
|
||||
if self._debug and self._http and self._http.response:
|
||||
ip = self.transport.get_extra_info("peername")
|
||||
logger.error(f"Connection lost before response written @ {ip}")
|
||||
except Exception:
|
||||
logger.exception("protocol.connection_lost")
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user