From 454286491292343a26a1eb678dfaa06c9f9f7bf2 Mon Sep 17 00:00:00 2001 From: Adam Hopkins Date: Tue, 25 Jun 2024 14:41:32 +0300 Subject: [PATCH 1/2] Catch request middleware exceptions --- sanic/app.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/sanic/app.py b/sanic/app.py index cc551daa59..b9cd8ed1e5 100644 --- a/sanic/app.py +++ b/sanic/app.py @@ -1209,10 +1209,15 @@ async def handle_exception( # Request Middleware # -------------------------------------------- # if run_middleware: - middleware = ( - request.route and request.route.extra.request_middleware - ) or self.request_middleware - response = await self._run_request_middleware(request, middleware) + try: + middleware = ( + request.route and request.route.extra.request_middleware + ) or self.request_middleware + response = await self._run_request_middleware( + request, middleware + ) + except Exception as e: + return await self.handle_exception(request, e, False) # No middleware results if not response: try: From 90e26e4a0cc9dbd5d4e8c260af12bcaf14569836 Mon Sep 17 00:00:00 2001 From: Adam Hopkins Date: Sun, 30 Jun 2024 09:03:00 +0300 Subject: [PATCH 2/2] Add test --- tests/test_exceptions.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py index 7932eb6dfb..b945eadea0 100644 --- a/tests/test_exceptions.py +++ b/tests/test_exceptions.py @@ -1,5 +1,7 @@ import logging +from itertools import count + import pytest from bs4 import BeautifulSoup @@ -413,3 +415,21 @@ class CustomError(SanicException): assert CustomError().message == CustomError.message == str(CustomError()) assert SanicException().message != "" assert SanicException("").message == "" + + +def test_request_middleware_exception_on_404(app: Sanic): + """See https://github.com/sanic-org/sanic/issues/2950""" + counter = count() + + @app.on_request + def request_middleware(request): + value = next(counter) + raise Exception + + @app.route("/") + async def handler(request): ... + + _, response = app.test_client.get("/not-found") + + assert response.status == 500 + assert next(counter) == 1