diff --git a/sanic/router.py b/sanic/router.py index 2581e178..691f1388 100644 --- a/sanic/router.py +++ b/sanic/router.py @@ -351,7 +351,10 @@ class Router: :param request: Request object :return: bool """ - handler = self.get(request)[0] + try: + handler = self.get(request)[0] + except (NotFound, InvalidUsage): + return False if (hasattr(handler, 'view_class') and hasattr(handler.view_class, request.method.lower())): handler = getattr(handler.view_class, request.method.lower()) diff --git a/sanic/worker.py b/sanic/worker.py index d15fda41..1d3e384b 100644 --- a/sanic/worker.py +++ b/sanic/worker.py @@ -159,6 +159,7 @@ class GunicornWorker(base.Worker): def handle_quit(self, sig, frame): self.alive = False + self.app.callable.is_running = False self.cfg.worker_int(self) def handle_abort(self, sig, frame): diff --git a/tests/test_request_stream.py b/tests/test_request_stream.py index 0ceccf60..4ca4e44e 100644 --- a/tests/test_request_stream.py +++ b/tests/test_request_stream.py @@ -163,6 +163,34 @@ def test_request_stream_app(): assert response.text == data +def test_request_stream_handle_exception(): + '''for handling exceptions properly''' + + app = Sanic('test_request_stream_exception') + + @app.post('/post/', stream=True) + async def post(request, id): + assert isinstance(request.stream, asyncio.Queue) + + async def streaming(response): + while True: + body = await request.stream.get() + if body is None: + break + response.write(body.decode('utf-8')) + return stream(streaming) + + # 404 + request, response = app.test_client.post('/in_valid_post', data=data) + assert response.status == 404 + assert response.text == 'Error: Requested URL /in_valid_post not found' + + # 405 + request, response = app.test_client.get('/post/random_id', data=data) + assert response.status == 405 + assert response.text == 'Error: Method GET not allowed for URL /post/random_id' + + def test_request_stream_blueprint(): '''for self.is_request_stream = True'''