Skip to content

Commit

Permalink
Reverted the streaming response code in potel
Browse files Browse the repository at this point in the history
  • Loading branch information
antonpirker committed Dec 2, 2024
1 parent bddf9b5 commit f0a6f5e
Showing 1 changed file with 32 additions and 64 deletions.
96 changes: 32 additions & 64 deletions sentry_sdk/integrations/wsgi.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import sys
from contextlib import nullcontext
from functools import partial

import sentry_sdk
Expand All @@ -11,7 +12,6 @@
)
from sentry_sdk.sessions import track_session
from sentry_sdk.tracing import Transaction, TRANSACTION_SOURCE_ROUTE
from sentry_sdk.tracing_utils import finish_running_transaction
from sentry_sdk.utils import (
ContextVar,
capture_internal_exceptions,
Expand Down Expand Up @@ -44,9 +44,6 @@ def __call__(self, status, response_headers, exc_info=None): # type: ignore
pass


MAX_TRANSACTION_DURATION_SECONDS = 5 * 60


_wsgi_middleware_applied = ContextVar("sentry_wsgi_middleware_applied")

DEFAULT_TRANSACTION_NAME = "generic WSGI request"
Expand Down Expand Up @@ -113,7 +110,6 @@ def __call__(self, environ, start_response):
scope.set_transaction_name(
DEFAULT_TRANSACTION_NAME, source=TRANSACTION_SOURCE_ROUTE
)
current_scope = sentry_sdk.get_current_scope()

with track_session(scope, session_mode="request"):
with capture_internal_exceptions():
Expand All @@ -124,14 +120,11 @@ def __call__(self, environ, start_response):
environ, self.use_x_forwarded_for
)
)

method = environ.get("REQUEST_METHOD", "").upper()
should_trace = method in self.http_methods_to_capture
transaction = None

with sentry_sdk.continue_trace(environ):
if should_trace:
transaction = sentry_sdk.start_span(
with (
sentry_sdk.start_span(
op=OP.HTTP_SERVER,
name=DEFAULT_TRANSACTION_NAME,
source=TRANSACTION_SOURCE_ROUTE,
Expand All @@ -140,9 +133,9 @@ def __call__(self, environ, start_response):
environ, self.use_x_forwarded_for
),
)
transaction.__enter__()
current_scope = transaction.scope

if should_trace
else nullcontext()
) as transaction:
try:
response = self.app(
environ,
Expand All @@ -153,20 +146,12 @@ def __call__(self, environ, start_response):
),
)
except BaseException:
exc_info = sys.exc_info()
_capture_exception(exc_info)
finish_running_transaction(transaction, exc_info)
reraise(*exc_info)
reraise(*_capture_exception())

finally:
_wsgi_middleware_applied.set(False)

return _ScopedResponse(
response=response,
current_scope=current_scope,
isolation_scope=scope,
transaction=transaction,
)
return _ScopedResponse(scope, response)


def _sentry_start_response( # type: ignore
Expand Down Expand Up @@ -228,13 +213,13 @@ def get_client_ip(environ):
return environ.get("REMOTE_ADDR")


def _capture_exception(exc_info=None):
# type: (Optional[ExcInfo]) -> ExcInfo
def _capture_exception():
# type: () -> ExcInfo
"""
Captures the current exception and sends it to Sentry.
Returns the ExcInfo tuple to it can be reraised afterwards.
"""
exc_info = exc_info or sys.exc_info()
exc_info = sys.exc_info()
e = exc_info[1]

# SystemExit(0) is the only uncaught exception that is expected behavior
Expand All @@ -252,7 +237,7 @@ def _capture_exception(exc_info=None):

class _ScopedResponse:
"""
Use separate scopes for each response chunk.
Users a separate scope for each response chunk.
This will make WSGI apps more tolerant against:
- WSGI servers streaming responses from a different thread/from
Expand All @@ -261,54 +246,37 @@ class _ScopedResponse:
- WSGI servers streaming responses interleaved from the same thread
"""

__slots__ = ("_response", "_current_scope", "_isolation_scope", "_transaction")
__slots__ = ("_response", "_scope")

def __init__(
self,
response, # type: Iterator[bytes]
current_scope, # type: sentry_sdk.scope.Scope
isolation_scope, # type: sentry_sdk.scope.Scope
transaction=None, # type: Optional[Transaction]
):
# type: (...) -> None
def __init__(self, scope, response):
# type: (sentry_sdk.scope.Scope, Iterator[bytes]) -> None
self._scope = scope
self._response = response
self._current_scope = current_scope
self._isolation_scope = isolation_scope
self._transaction = transaction

def __iter__(self):
# type: () -> Iterator[bytes]
iterator = iter(self._response)

try:
while True:
with sentry_sdk.use_isolation_scope(self._isolation_scope):
with sentry_sdk.use_scope(self._current_scope):
try:
chunk = next(iterator)
except StopIteration:
break
except BaseException:
reraise(*_capture_exception())

yield chunk
while True:
with sentry_sdk.use_isolation_scope(self._scope):
try:
chunk = next(iterator)
except StopIteration:
break
except BaseException:
reraise(*_capture_exception())

finally:
with sentry_sdk.use_isolation_scope(self._isolation_scope):
with sentry_sdk.use_scope(self._current_scope):
finish_running_transaction(transaction=self._transaction)
yield chunk

def close(self):
# type: () -> None
with sentry_sdk.use_isolation_scope(self._isolation_scope):
with sentry_sdk.use_scope(self._current_scope):
try:
finish_running_transaction(transaction=self._transaction)
self._response.close() # type: ignore
except AttributeError:
pass
except BaseException:
reraise(*_capture_exception())
with sentry_sdk.use_isolation_scope(self._scope):
try:
self._response.close() # type: ignore
except AttributeError:
pass
except BaseException:
reraise(*_capture_exception())


def _make_wsgi_event_processor(environ, use_x_forwarded_for):
Expand Down

0 comments on commit f0a6f5e

Please sign in to comment.