1313from sentry_sdk .integrations ._wsgi_common import RequestExtractor , _filter_headers
1414from sentry_sdk .integrations .logging import ignore_logger
1515
16- from sanic import Sanic # type: ignore
16+ from sanic import Sanic , __version__ as VERSION # type: ignore
1717from sanic .exceptions import SanicException # type: ignore
1818from sanic .router import Router # type: ignore
1919from sanic .handlers import ErrorHandler # type: ignore
2424 from typing import Any
2525 from typing import Callable
2626 from typing import Dict
27- from typing import List
28- from typing import Tuple
29- from sanic .exceptions import InvalidUsage
3027 from typing import Optional
3128 from typing import Union
29+ from typing import Tuple
3230 from sanic .request import RequestParameters
3331
3432
@@ -46,12 +44,17 @@ def setup_once():
4644 " or aiocontextvars package"
4745 )
4846
49- # Sanic 0.8 and older creates a logger named "root" and puts a
50- # stringified version of every exception in there (without exc_info),
51- # which our error deduplication can't detect.
52- #
53- # https://github.com/huge-success/sanic/issues/1332
54- ignore_logger ("root" )
47+ if VERSION .startswith ("0.8." ):
48+ # Sanic 0.8 and older creates a logger named "root" and puts a
49+ # stringified version of every exception in there (without exc_info),
50+ # which our error deduplication can't detect.
51+ #
52+ # We explicitly check the version here because it is a very
53+ # invasive step to ignore this logger and not necessary in newer
54+ # versions at all.
55+ #
56+ # https://github.com/huge-success/sanic/issues/1332
57+ ignore_logger ("root" )
5558
5659 old_handle_request = Sanic .handle_request
5760
@@ -79,7 +82,7 @@ async def sentry_handle_request(self, request, *args, **kwargs):
7982 old_router_get = Router .get
8083
8184 def sentry_router_get (self , request ):
82- # type: (Any, Request) -> Tuple[Callable, List, Dict[str, str], str]
85+ # type: (Any, Request) -> Any
8386 rv = old_router_get (self , request )
8487 hub = Hub .current
8588 if hub .get_integration (SanicIntegration ) is not None :
@@ -93,7 +96,7 @@ def sentry_router_get(self, request):
9396 old_error_handler_lookup = ErrorHandler .lookup
9497
9598 def sentry_error_handler_lookup (self , exception ):
96- # type: (Any, Union[ValueError, InvalidUsage] ) -> Optional[Callable]
99+ # type: (Any, Exception ) -> Optional[Callable]
97100 _capture_exception (exception )
98101 old_error_handler = old_error_handler_lookup (self , exception )
99102
@@ -104,13 +107,16 @@ def sentry_error_handler_lookup(self, exception):
104107 return old_error_handler
105108
106109 async def sentry_wrapped_error_handler (request , exception ):
107- # type: (Request, ValueError ) -> Any
110+ # type: (Request, Exception ) -> Any
108111 try :
109112 response = old_error_handler (request , exception )
110113 if isawaitable (response ):
111114 response = await response
112115 return response
113116 except Exception :
117+ # Report errors that occur in Sanic error handler. These
118+ # exceptions will not even show up in Sanic's
119+ # `sanic.exceptions` logger.
114120 exc_info = sys .exc_info ()
115121 _capture_exception (exc_info )
116122 reraise (* exc_info )
@@ -120,13 +126,8 @@ async def sentry_wrapped_error_handler(request, exception):
120126 ErrorHandler .lookup = sentry_error_handler_lookup
121127
122128
123- def _capture_exception (
124- exception # type: Union[Tuple[type, BaseException, Any], ValueError, InvalidUsage]
125- ):
126- # type: (...) -> None
127- if isinstance (exception , SanicException ):
128- return
129-
129+ def _capture_exception (exception ):
130+ # type: (Union[Tuple[Optional[type], Optional[BaseException], Any], BaseException]) -> None
130131 hub = Hub .current
131132 integration = hub .get_integration (SanicIntegration )
132133 if integration is None :
@@ -144,7 +145,14 @@ def _capture_exception(
144145def _make_request_processor (weak_request ):
145146 # type: (Callable[[], Request]) -> Callable
146147 def sanic_processor (event , hint ):
147- # type: (Dict[str, Any], Dict[str, Any]) -> Dict[str, Any]
148+ # type: (Dict[str, Any], Dict[str, Any]) -> Optional[Dict[str, Any]]
149+
150+ try :
151+ if issubclass (hint ["exc_info" ][0 ], SanicException ):
152+ return None
153+ except KeyError :
154+ pass
155+
148156 request = weak_request ()
149157 if request is None :
150158 return event
0 commit comments