diff --git a/scripts/populate_tox/config.py b/scripts/populate_tox/config.py index 99bf31706c..2f52202fae 100644 --- a/scripts/populate_tox/config.py +++ b/scripts/populate_tox/config.py @@ -399,7 +399,7 @@ "package": "quart", "deps": { "*": ["quart-auth", "pytest-asyncio", "pytest-forked", "Werkzeug"], - ">=0.19": ["quart-flask-patch"], + ">=0.19,<0.23": ["quart-flask-patch"], "<0.19": [ "blinker<1.6", "jinja2<3.1.0", diff --git a/tests/integrations/quart/test_quart.py b/tests/integrations/quart/test_quart.py index c93a6f3186..b9fc2d5f15 100644 --- a/tests/integrations/quart/test_quart.py +++ b/tests/integrations/quart/test_quart.py @@ -92,6 +92,10 @@ def integration_enabled_params(request): sys.version_info >= (3, 14), reason="quart_flask_patch not working on 3.14 (yet?)", ) +@pytest.mark.skipif( + QUART_VERSION >= (0, 23), + reason="quart_flask_patch is incompatible with quart>=0.23 RequestContext changes", +) async def test_quart_flask_patch(sentry_init, capture_events, reset_integrations): # This testcase is forked because `import quart_flask_patch` needs to run # before anything else Quart-related is imported (since it monkeypatches @@ -417,6 +421,28 @@ async def error_handler(err): (exception,) = event["exception"]["values"] assert exception["type"] == "ValueError" + elif QUART_VERSION >= (0, 23): + # Starting in 0.23 (db05772), Quart runs request handling inside an + # asyncio.TaskGroup, so the ZeroDivisionError propagates wrapped + # in an ExceptionGroup instead of bare. + with pytest.raises(ExceptionGroup) as exc_info: # noqa: F821 + await client.get("/") + + (exception,) = exc_info.value.exceptions + assert isinstance(exception, ZeroDivisionError) + + event1, event2 = events + + (exception,) = event1["exception"]["values"] + assert exception["type"] == "ValueError" + + # event2's exception chain is [ValueError, ZeroDivisionError, + # ExceptionGroup]: the ValueError that triggered the errorhandler, + # the ZeroDivisionError raised inside it, and the ExceptionGroup + # Quart's TaskGroup wraps them in. + exception_types = [e["type"] for e in event2["exception"]["values"]] + assert exception_types == ["ValueError", "ZeroDivisionError", "ExceptionGroup"] + else: with pytest.raises(ZeroDivisionError): await client.get("/")