99from sentry_sdk .utils import (
1010 capture_internal_exceptions ,
1111 event_from_exception ,
12+ transaction_from_function ,
1213 HAS_REAL_CONTEXTVARS ,
1314)
1415
1516import asyncio
16- from aiohttp .web import Application , HTTPException # type: ignore
17+ from aiohttp .web import Application , HTTPException , UrlDispatcher # type: ignore
1718
1819from sentry_sdk ._types import MYPY
1920
2021if MYPY :
2122 from aiohttp .web_request import Request # type: ignore
23+ from aiohttp .abc import AbstractMatchInfo # type: ignore
2224 from typing import Any
2325 from typing import Dict
2426 from typing import Tuple
2527 from typing import Callable
2628
2729 from sentry_sdk .utils import ExcInfo
30+ from sentry_sdk ._types import EventProcessor
2831
2932
3033class AioHttpIntegration (Integration ):
@@ -60,14 +63,17 @@ async def inner():
6063 scope .clear_breadcrumbs ()
6164 scope .add_event_processor (_make_request_processor (weak_request ))
6265
63- try :
64- response = await old_handle (self , request )
65- except HTTPException :
66- raise
67- except Exception :
68- reraise (* _capture_exception (hub ))
66+ # If this transaction name makes it to the UI, AIOHTTP's
67+ # URL resolver did not find a route or died trying.
68+ with hub .span (transaction = "generic AIOHTTP request" ):
69+ try :
70+ response = await old_handle (self , request )
71+ except HTTPException :
72+ raise
73+ except Exception :
74+ reraise (* _capture_exception (hub ))
6975
70- return response
76+ return response
7177
7278 # Explicitly wrap in task such that current contextvar context is
7379 # copied. Just doing `return await inner()` will leak scope data
@@ -76,9 +82,30 @@ async def inner():
7682
7783 Application ._handle = sentry_app_handle
7884
85+ old_urldispatcher_resolve = UrlDispatcher .resolve
86+
87+ async def sentry_urldispatcher_resolve (self , request ):
88+ # type: (UrlDispatcher, Request) -> AbstractMatchInfo
89+ rv = await old_urldispatcher_resolve (self , request )
90+
91+ name = None
92+
93+ try :
94+ name = transaction_from_function (rv .handler )
95+ except Exception :
96+ pass
97+
98+ if name is not None :
99+ with Hub .current .configure_scope () as scope :
100+ scope .transaction = name
101+
102+ return rv
103+
104+ UrlDispatcher .resolve = sentry_urldispatcher_resolve
105+
79106
80107def _make_request_processor (weak_request ):
81- # type: (Callable[[], Request]) -> Callable
108+ # type: (Callable[[], Request]) -> EventProcessor
82109 def aiohttp_processor (
83110 event , # type: Dict[str, Any]
84111 hint , # type: Dict[str, Tuple[type, BaseException, Any]]
0 commit comments