From 654a85f46b7dd7a1e94f81193c4a78a8a1e99936 Mon Sep 17 00:00:00 2001 From: Miguel Grinberg Date: Sun, 18 May 2025 12:20:50 +0100 Subject: [PATCH] Do not silence exceptions that occur in the SSE task --- src/microdot/sse.py | 13 +++++++++++-- tests/test_sse.py | 12 ++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/microdot/sse.py b/src/microdot/sse.py index 2c4ff08..33a88b4 100644 --- a/src/microdot/sse.py +++ b/src/microdot/sse.py @@ -61,7 +61,12 @@ def sse_response(request, event_function, *args, **kwargs): sse = SSE() async def sse_task_wrapper(): - await event_function(request, sse, *args, **kwargs) + try: + await event_function(request, sse, *args, **kwargs) + except Exception as exc: + # the SSE task raised an exception so we need to pass it to the + # main route so that it is re-raised there + sse.queue.append(exc) sse.event.set() task = asyncio.create_task(sse_task_wrapper()) @@ -79,7 +84,11 @@ def sse_response(request, event_function, *args, **kwargs): except IndexError: await sse.event.wait() sse.event.clear() - if event is None: + if isinstance(event, Exception): + # if the event is an exception we re-raise it here so that it + # can be handled appropriately + raise event + elif event is None: raise StopAsyncIteration return event diff --git a/tests/test_sse.py b/tests/test_sse.py index 0fcb6c2..cf2f8db 100644 --- a/tests/test_sse.py +++ b/tests/test_sse.py @@ -42,3 +42,15 @@ class TestWebSocket(unittest.TestCase): 'data: [42, "foo", "bar"]\n\n' 'data: foo\n\n' 'data: foo\n\n')) + + def test_sse_exception(self): + app = Microdot() + + @app.route('/sse') + @with_sse + async def handle_sse(request, sse): + await sse.send('foo') + await sse.send(1 / 0) + + client = TestClient(app) + self.assertRaises(ZeroDivisionError, self._run, client.get('/sse'))