@@ -168,62 +168,66 @@ def patch_exception_middleware(middleware_class):
168168 """
169169 old_middleware_init = middleware_class .__init__
170170
171- def _sentry_middleware_init (self , * args , ** kwargs ):
172- # type: (Any, Any, Any) -> None
173- old_middleware_init (self , * args , ** kwargs )
171+ not_yet_patched = "_sentry_middleware_init" not in str (old_middleware_init )
174172
175- # Patch existing exception handlers
176- old_handlers = self ._exception_handlers .copy ()
173+ if not_yet_patched :
177174
178- async def _sentry_patched_exception_handler (self , * args , ** kwargs ):
175+ def _sentry_middleware_init (self , * args , ** kwargs ):
179176 # type: (Any, Any, Any) -> None
180- exp = args [0 ]
181-
182- is_http_server_error = (
183- hasattr (exp , "status_code" ) and exp .status_code >= 500
184- )
185- if is_http_server_error :
186- _capture_exception (exp , handled = True )
187-
188- # Find a matching handler
189- old_handler = None
190- for cls in type (exp ).__mro__ :
191- if cls in old_handlers :
192- old_handler = old_handlers [cls ]
193- break
194-
195- if old_handler is None :
196- return
197-
198- if _is_async_callable (old_handler ):
199- return await old_handler (self , * args , ** kwargs )
200- else :
201- return old_handler (self , * args , ** kwargs )
177+ old_middleware_init (self , * args , ** kwargs )
202178
203- for key in self . _exception_handlers . keys ():
204- self . _exception_handlers [ key ] = _sentry_patched_exception_handler
179+ # Patch existing exception handlers
180+ old_handlers = self . _exception_handlers . copy ()
205181
206- middleware_class .__init__ = _sentry_middleware_init
182+ async def _sentry_patched_exception_handler (self , * args , ** kwargs ):
183+ # type: (Any, Any, Any) -> None
184+ exp = args [0 ]
207185
208- old_call = middleware_class .__call__
209-
210- async def _sentry_exceptionmiddleware_call (self , scope , receive , send ):
211- # type: (Dict[str, Any], Dict[str, Any], Callable[[], Awaitable[Dict[str, Any]]], Callable[[Dict[str, Any]], Awaitable[None]]) -> None
212- # Also add the user (that was eventually set by be Authentication middle
213- # that was called before this middleware). This is done because the authentication
214- # middleware sets the user in the scope and then (in the same function)
215- # calls this exception middelware. In case there is no exception (or no handler
216- # for the type of exception occuring) then the exception bubbles up and setting the
217- # user information into the sentry scope is done in auth middleware and the
218- # ASGI middleware will then send everything to Sentry and this is fine.
219- # But if there is an exception happening that the exception middleware here
220- # has a handler for, it will send the exception directly to Sentry, so we need
221- # the user information right now.
222- # This is why we do it here.
223- _add_user_to_sentry_scope (scope )
224- await old_call (self , scope , receive , send )
225-
226- middleware_class .__call__ = _sentry_exceptionmiddleware_call
186+ is_http_server_error = (
187+ hasattr (exp , "status_code" ) and exp .status_code >= 500
188+ )
189+ if is_http_server_error :
190+ _capture_exception (exp , handled = True )
191+
192+ # Find a matching handler
193+ old_handler = None
194+ for cls in type (exp ).__mro__ :
195+ if cls in old_handlers :
196+ old_handler = old_handlers [cls ]
197+ break
198+
199+ if old_handler is None :
200+ return
201+
202+ if _is_async_callable (old_handler ):
203+ return await old_handler (self , * args , ** kwargs )
204+ else :
205+ return old_handler (self , * args , ** kwargs )
206+
207+ for key in self ._exception_handlers .keys ():
208+ self ._exception_handlers [key ] = _sentry_patched_exception_handler
209+
210+ middleware_class .__init__ = _sentry_middleware_init
211+
212+ old_call = middleware_class .__call__
213+
214+ async def _sentry_exceptionmiddleware_call (self , scope , receive , send ):
215+ # type: (Dict[str, Any], Dict[str, Any], Callable[[], Awaitable[Dict[str, Any]]], Callable[[Dict[str, Any]], Awaitable[None]]) -> None
216+ # Also add the user (that was eventually set by be Authentication middle
217+ # that was called before this middleware). This is done because the authentication
218+ # middleware sets the user in the scope and then (in the same function)
219+ # calls this exception middelware. In case there is no exception (or no handler
220+ # for the type of exception occuring) then the exception bubbles up and setting the
221+ # user information into the sentry scope is done in auth middleware and the
222+ # ASGI middleware will then send everything to Sentry and this is fine.
223+ # But if there is an exception happening that the exception middleware here
224+ # has a handler for, it will send the exception directly to Sentry, so we need
225+ # the user information right now.
226+ # This is why we do it here.
227+ _add_user_to_sentry_scope (scope )
228+ await old_call (self , scope , receive , send )
229+
230+ middleware_class .__call__ = _sentry_exceptionmiddleware_call
227231
228232
229233def _add_user_to_sentry_scope (scope ):
@@ -268,12 +272,16 @@ def patch_authentication_middleware(middleware_class):
268272 """
269273 old_call = middleware_class .__call__
270274
271- async def _sentry_authenticationmiddleware_call (self , scope , receive , send ):
272- # type: (Dict[str, Any], Dict[str, Any], Callable[[], Awaitable[Dict[str, Any]]], Callable[[Dict[str, Any]], Awaitable[None]]) -> None
273- await old_call (self , scope , receive , send )
274- _add_user_to_sentry_scope (scope )
275+ not_yet_patched = "_sentry_authenticationmiddleware_call" not in str (old_call )
276+
277+ if not_yet_patched :
278+
279+ async def _sentry_authenticationmiddleware_call (self , scope , receive , send ):
280+ # type: (Dict[str, Any], Dict[str, Any], Callable[[], Awaitable[Dict[str, Any]]], Callable[[Dict[str, Any]], Awaitable[None]]) -> None
281+ await old_call (self , scope , receive , send )
282+ _add_user_to_sentry_scope (scope )
275283
276- middleware_class .__call__ = _sentry_authenticationmiddleware_call
284+ middleware_class .__call__ = _sentry_authenticationmiddleware_call
277285
278286
279287def patch_middlewares ():
0 commit comments