def test_dedupe_event_processor_drop_records_client_report( sentry_init, capture_events, capture_client_reports): """ DedupeIntegration internally has an event_processor that filters duplicate exceptions. We want a duplicate exception to be captured only once and the drop being recorded as a client report. """ sentry_init() events = capture_events() reports = capture_client_reports() try: raise ValueError("aha!") except Exception: try: capture_exception() reraise(*sys.exc_info()) except Exception: capture_exception() (event, ) = events (report, ) = reports assert event["level"] == "error" assert "exception" in event assert report == ("event_processor", "error")
def __call__(self, event, context): # type: (Any, Any) -> Any hub = Hub.current client = hub.client # type: Any with hub.push_scope() as scope: with capture_internal_exceptions(): configured_time = context.get_remaining_time_in_millis() scope.add_event_processor( _make_request_event_processor(event, context, configured_time)) try: event_obj = self.event_class(event, context) return self.func(event_obj) except Exception: exc_info = sys.exc_info() event, hint = event_from_exception( exc_info, client_options=client.options, mechanism={ "type": "chalice", "handled": False }, ) hub.capture_event(event, hint=hint) hub.flush() reraise(*exc_info)
def sentry_handler(event, context, *args, **kwargs): # type: (Any, Any, *Any, **Any) -> Any hub = Hub.current integration = hub.get_integration(AwsLambdaIntegration) if integration is None: return handler(event, context, *args, **kwargs) # If an integration is there, a client has to be there. client = hub.client # type: Any with hub.push_scope() as scope: with capture_internal_exceptions(): scope.clear_breadcrumbs() scope.transaction = context.function_name scope.add_event_processor( _make_request_event_processor(event, context)) try: return handler(event, context, *args, **kwargs) except Exception: exc_info = sys.exc_info() event, hint = event_from_exception( exc_info, client_options=client.options, mechanism={ "type": "aws_lambda", "handled": False }, ) hub.capture_event(event, hint=hint) reraise(*exc_info)
def __call__(self, environ, start_response): # type: (Dict[str, str], Callable[..., Any]) -> _ScopedResponse if _wsgi_middleware_applied.get(False): return self.app(environ, start_response) _wsgi_middleware_applied.set(True) try: hub = Hub(Hub.current) with auto_session_tracking(hub, session_mode="request"): with hub: with capture_internal_exceptions(): with hub.configure_scope() as scope: scope.clear_breadcrumbs() scope._name = "wsgi" scope.add_event_processor( _make_wsgi_event_processor(environ)) transaction = Transaction.continue_from_environ( environ, op="http.server", name="generic WSGI request") with hub.start_transaction( transaction, custom_sampling_context={"wsgi_environ": environ}): try: rv = self.app( environ, partial(_sentry_start_response, start_response, transaction), ) except BaseException: reraise(*_capture_exception(hub)) finally: _wsgi_middleware_applied.set(False) return _ScopedResponse(hub, rv)
async def inner(): # type: () -> Any hub = Hub.current if hub.get_integration(AioHttpIntegration) is None: return await old_handle(self, request, *args, **kwargs) weak_request = weakref.ref(request) with Hub(Hub.current) as hub: with hub.configure_scope() as scope: scope.clear_breadcrumbs() scope.add_event_processor( _make_request_processor(weak_request)) # If this transaction name makes it to the UI, AIOHTTP's # URL resolver did not find a route or died trying. with hub.start_span(transaction="generic AIOHTTP request"): try: response = await old_handle(self, request) except HTTPException: raise except Exception: reraise(*_capture_exception(hub)) return response
async def inner(): # type: () -> Any hub = Hub.current if hub.get_integration(AioHttpIntegration) is None: return await old_handle(self, request, *args, **kwargs) weak_request = weakref.ref(request) with Hub(Hub.current) as hub: with hub.configure_scope() as scope: scope.clear_breadcrumbs() scope.add_event_processor( _make_request_processor(weak_request)) span = Span.continue_from_headers(request.headers) span.op = "http.server" # If this transaction name makes it to the UI, AIOHTTP's # URL resolver did not find a route or died trying. span.transaction = "generic AIOHTTP request" with hub.start_span(span): try: response = await old_handle(self, request) except HTTPException as e: span.set_http_status(e.status_code) raise except Exception: # This will probably map to a 500 but seems like we # have no way to tell. Do not set span status. reraise(*_capture_exception(hub)) span.set_http_status(response.status) return response
def sentry_handler(event, context, *args, **kwargs): hub = Hub.current with hub.push_scope(): with capture_internal_exceptions(): with configure_scope() as scope: scope.transaction = context.function_name scope.add_event_processor( _make_request_event_processor(event, context)) try: return handler(event, context, *args, **kwargs) except Exception: exc_info = sys.exc_info() event, hint = event_from_exception( exc_info, with_locals=hub.client.options["with_locals"], mechanism={ "type": "aws_lambda", "handled": False }, ) hub.capture_event(event, hint=hint) reraise(*exc_info) finally: client = hub.client # Flush out the event queue before AWS kills the # process. This is not threadsafe. if client is not None: # make new transport with empty queue new_transport = client.transport.copy() client.close() client.transport = new_transport
def sentry_patched_inner_wsgi_call(environ, start_response): try: return old_wsgi_call(self, environ, start_response) except Exception: einfo = sys.exc_info() _capture_exception(einfo) reraise(*einfo)
def __call__(self, environ, start_response): # type: (Dict[str, str], Callable[..., Any]) -> _ScopedResponse if _wsgi_middleware_applied.get(False): return self.app(environ, start_response) _wsgi_middleware_applied.set(True) try: hub = Hub(Hub.current) with hub: with capture_internal_exceptions(): with hub.configure_scope() as scope: scope.clear_breadcrumbs() scope._name = "wsgi" scope.add_event_processor( _make_wsgi_event_processor(environ)) span = Span.continue_from_environ(environ) span.op = "http.server" span.transaction = "generic WSGI request" with hub.start_span(span) as span: try: rv = self.app( environ, functools.partial(_sentry_start_response, start_response, span), ) except BaseException: reraise(*_capture_exception(hub)) finally: _wsgi_middleware_applied.set(False) return _ScopedResponse(hub, rv)
def close(self): self._hub.pop_scope_unsafe() if hasattr(self._response, "close"): try: self._response.close() except Exception: reraise(*_capture_exception(self.hub))
def __next__(self): try: return next(self._response) except StopIteration: raise except Exception: reraise(*_capture_exception(self.hub))
def run(*a, **kw): hub = parent_hub or Hub.current with hub: try: self = current_thread() return old_run_func(self, *a, **kw) except Exception: reraise(*_capture_exception())
def sentry_patched_inner_wsgi_call(environ, start_response): # type: (Dict[str, Any], Callable[..., Any]) -> Any try: return old_wsgi_call(self, environ, start_response) except Exception: einfo = sys.exc_info() _capture_exception(einfo) reraise(*einfo)
def _inner(*args, **kwargs): try: return f(*args, **kwargs) except Exception: exc_info = sys.exc_info() with capture_internal_exceptions(): _capture_exception(task, exc_info) reraise(*exc_info)
def close(self): with self._hub: try: self._response.close() except AttributeError: pass except Exception: reraise(*_capture_exception(self._hub))
def run(*a, **kw): hub = parent_hub or Hub.current with hub: try: return old_run(*a, **kw) except Exception: reraise(*_capture_exception())
def sentry_handler(event, context, *args, **kwargs): # type: (Any, Any, *Any, **Any) -> Any hub = Hub.current integration = hub.get_integration(AwsLambdaIntegration) if integration is None: return handler(event, context, *args, **kwargs) # If an integration is there, a client has to be there. client = hub.client # type: Any configured_time = context.get_remaining_time_in_millis() with hub.push_scope() as scope: with capture_internal_exceptions(): scope.clear_breadcrumbs() scope.add_event_processor( _make_request_event_processor(event, context, configured_time)) scope.set_tag("aws_region", context.invoked_function_arn.split(":")[3]) timeout_thread = None # Starting the Timeout thread only if the configured time is greater than Timeout warning # buffer and timeout_warning parameter is set True. if (integration.timeout_warning and configured_time > TIMEOUT_WARNING_BUFFER): waiting_time = (configured_time - TIMEOUT_WARNING_BUFFER) / MILLIS_TO_SECONDS timeout_thread = TimeoutThread( waiting_time, configured_time / MILLIS_TO_SECONDS, ) # Starting the thread to raise timeout warning exception timeout_thread.start() headers = event.get("headers", {}) transaction = Transaction.continue_from_headers( headers, op="serverless.function", name=context.function_name) with hub.start_transaction(transaction): try: return handler(event, context, *args, **kwargs) except Exception: exc_info = sys.exc_info() event, hint = event_from_exception( exc_info, client_options=client.options, mechanism={ "type": "aws_lambda", "handled": False }, ) hub.capture_event(event, hint=hint) reraise(*exc_info) finally: if timeout_thread: timeout_thread.stop()
def close(self): # type: () -> None with self._hub: try: self._response.close() # type: ignore except AttributeError: pass except BaseException: reraise(*_capture_exception(self._hub))
def __next__(self): if self._iterator is None: self.__iter__() try: return next(self._iterator) except StopIteration: raise except Exception: reraise(*_capture_exception(self._hub))
async def sentry_wrapped_error_handler(request, exception): try: response = old_error_handler(request, exception) if isawaitable(response): response = await response return response except Exception: exc_info = sys.exc_info() _capture_exception(exc_info) reraise(*exc_info)
def sentry_func(*args, **kwargs): # type: (*Any, **Any) -> Any hub = Hub.current integration = hub.get_integration(GcpIntegration) if integration is None: return func(*args, **kwargs) # If an integration is there, a client has to be there. client = hub.client # type: Any configured_time = environ.get("FUNCTION_TIMEOUT_SEC") if not configured_time: logger.debug( "The configured timeout could not be fetched from Cloud Functions configuration." ) return func(*args, **kwargs) configured_time = int(configured_time) initial_time = datetime.now() with hub.push_scope() as scope: with capture_internal_exceptions(): scope.clear_breadcrumbs() scope.transaction = environ.get("FUNCTION_NAME") scope.add_event_processor( _make_request_event_processor(configured_time, initial_time)) try: if (integration.timeout_warning and configured_time > TIMEOUT_WARNING_BUFFER): waiting_time = configured_time - TIMEOUT_WARNING_BUFFER timeout_thread = TimeoutThread(waiting_time, configured_time) # Starting the thread to raise timeout warning exception timeout_thread.start() return func(*args, **kwargs) except Exception: exc_info = sys.exc_info() event, hint = event_from_exception( exc_info, client_options=client.options, mechanism={ "type": "gcp", "handled": False }, ) hub.capture_event(event, hint=hint) reraise(*exc_info) finally: # Flush out the event queue hub.flush()
def raise_exception(client): """ Raise an exception. If the client is not in the hub, rebind it. """ hub = Hub.current if hub.client is None: hub.bind_client(client) exc_info = sys.exc_info() with capture_internal_exceptions(): _capture_exception(exc_info, hub) reraise(*exc_info)
def close(self): if not self._popped: self._hub.pop_scope_unsafe() self._popped = True try: self._response.close() except AttributeError: pass except Exception: reraise(*_capture_exception(self._hub))
def _capture_and_reraise(): # type: () -> None exc_info = sys.exc_info() hub = Hub.current if hub.client is not None: event, hint = event_from_exception( exc_info, client_options=hub.client.options, mechanism={"type": "serverless", "handled": False}, ) hub.capture_event(event, hint=hint) reraise(*exc_info)
def __iter__(self): iterator = iter(self._response) while True: with self._hub: try: chunk = next(iterator) except StopIteration: break except Exception: reraise(*_capture_exception(self._hub)) yield chunk
async def sentry_wrapped_error_handler(request, exception): # type: (Request, Exception) -> Any try: response = old_error_handler(request, exception) if isawaitable(response): response = await response return response except Exception: # Report errors that occur in Sanic error handler. These # exceptions will not even show up in Sanic's # `sanic.exceptions` logger. exc_info = sys.exc_info() _capture_exception(exc_info) reraise(*exc_info)
def run_wsgi_app(app, environ, start_response): hub = Hub.current hub.push_scope() with capture_internal_exceptions(): with hub.configure_scope() as scope: scope.add_event_processor(_make_wsgi_event_processor(environ)) try: rv = app(environ, start_response) except Exception: einfo = _capture_exception(hub) hub.pop_scope_unsafe() reraise(*einfo) return _ScopePoppingResponse(hub, rv)
def sentry_patched_handle_request(self, request, *args, **kwargs): hub = Hub.current integration = hub.get_integration(PyramidIntegration) if integration is None: return old_handle_request(self, request, *args, **kwargs) with hub.configure_scope() as scope: scope.add_event_processor( _make_event_processor(weakref.ref(request), integration)) try: return old_handle_request(self, request, *args, **kwargs) except Exception: exc_info = sys.exc_info() _capture_exception(exc_info) reraise(*exc_info)
def __call__(self, environ, start_response): hub = Hub(Hub.current) with hub: with capture_internal_exceptions(): with hub.configure_scope() as scope: scope._name = "wsgi" scope.add_event_processor( _make_wsgi_event_processor(environ)) try: rv = self.app(environ, start_response) except Exception: reraise(*_capture_exception(hub)) return _ScopedResponse(hub, rv)
async def sentry_wrapped_error_handler(request, exception): # type: (Request, Exception) -> Any try: response = old_error_handler(request, exception) if isawaitable(response): response = await response return response except Exception: # Report errors that occur in Sanic error handler. These # exceptions will not even show up in Sanic's # `sanic.exceptions` logger. exc_info = sys.exc_info() _capture_exception(exc_info) reraise(*exc_info) finally: # As mentioned in previous comment in _startup, this can be removed # after https://github.com/sanic-org/sanic/issues/2297 is resolved if SanicIntegration.version == (21, 9): await _hub_exit(request)