Skip to content

Commit d794c3a

Browse files
mitsuhikountitaker
authored andcommitted
feat(django,flask): Use a weakref request for the django event processor (#32)
* feat(django): Use a weakref request for the django event processor * feat(flask): Use weakrefs in flask integration
1 parent f155fc7 commit d794c3a

File tree

2 files changed

+44
-13
lines changed

2 files changed

+44
-13
lines changed

sentry_sdk/integrations/django.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from __future__ import absolute_import
22

3+
import weakref
4+
35
from django import VERSION as DJANGO_VERSION
46
from django.core import signals
57

@@ -55,18 +57,27 @@ def sentry_patched_wsgi_handler(self, environ, start_response):
5557
make_event_processor = self._make_event_processor
5658

5759
def sentry_patched_get_response(self, request):
58-
get_current_hub().add_event_processor(lambda: make_event_processor(request))
59-
60+
weak_request = weakref.ref(request)
61+
get_current_hub().add_event_processor(
62+
lambda: make_event_processor(weak_request)
63+
)
6064
return old_get_response(self, request)
6165

6266
BaseHandler.get_response = sentry_patched_get_response
6367

6468
signals.got_request_exception.connect(_got_request_exception)
6569

66-
def _make_event_processor(self, request):
70+
def _make_event_processor(self, weak_request):
6771
client_options = get_current_hub().client.options
6872

6973
def processor(event):
74+
# if the request is gone we are fine not logging the data from
75+
# it. This might happen if the processor is pushed away to
76+
# another thread.
77+
request = weak_request()
78+
if request is None:
79+
return
80+
7081
if "transaction" not in event:
7182
try:
7283
event["transaction"] = resolve(request.path).func.__name__

sentry_sdk/integrations/flask.py

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
from __future__ import absolute_import
22

3+
import weakref
4+
35
from sentry_sdk import capture_exception, get_current_hub
46
from sentry_sdk.hub import _internal_exceptions, _should_send_default_pii
57
from ._wsgi import RequestExtractor, run_wsgi_app
68
from . import Integration
79

810
try:
9-
from flask_login import current_user
11+
from flask_login import current_user as current_user_proxy
1012
except ImportError:
11-
current_user = None
13+
current_user_proxy = None
1214

1315
from flask import Flask, _request_ctx_stack, _app_ctx_stack
1416
from flask.signals import (
@@ -43,7 +45,22 @@ def _push_appctx(*args, **kwargs):
4345
# always want to push scope regardless of whether WSGI app might already
4446
# have (not the case for CLI for example)
4547
get_current_hub().push_scope()
46-
get_current_hub().add_event_processor(_make_event_processor)
48+
49+
app = getattr(_app_ctx_stack.top, "app", None)
50+
51+
try:
52+
weak_request = weakref.ref(_request_ctx_stack.top.request)
53+
except AttributeError:
54+
weak_request = lambda: None
55+
56+
try:
57+
weak_user = weakref.ref(current_user_proxy._get_current_object())
58+
except (AttributeError, RuntimeError, TypeError):
59+
weak_user = lambda: None
60+
61+
get_current_hub().add_event_processor(
62+
lambda: _make_event_processor(app, weak_request, weak_user)
63+
)
4764

4865

4966
def _pop_appctx(*args, **kwargs):
@@ -54,13 +71,16 @@ def _capture_exception(sender, exception, **kwargs):
5471
capture_exception(exception)
5572

5673

57-
def _make_event_processor():
58-
request = getattr(_request_ctx_stack.top, "request", None)
59-
app = getattr(_app_ctx_stack.top, "app", None)
74+
def _make_event_processor(app, weak_request, weak_user):
6075
client_options = get_current_hub().client.options
6176

6277
def event_processor(event):
63-
if request:
78+
request = weak_request()
79+
80+
# if the request is gone we are fine not logging the data from
81+
# it. This might happen if the processor is pushed away to
82+
# another thread.
83+
if request is not None:
6484
if "transaction" not in event:
6585
try:
6686
event["transaction"] = request.url_rule.endpoint
@@ -72,7 +92,7 @@ def event_processor(event):
7292

7393
if _should_send_default_pii():
7494
with _internal_exceptions():
75-
_set_user_info(request, event)
95+
_set_user_info(request, weak_user(), event)
7696

7797
with _internal_exceptions():
7898
_process_frames(app, event)
@@ -119,7 +139,7 @@ def size_of_file(self, file):
119139
return file.content_length
120140

121141

122-
def _set_user_info(request, event):
142+
def _set_user_info(request, user, event):
123143
if "user" in event:
124144
return
125145

@@ -134,7 +154,7 @@ def _set_user_info(request, event):
134154
user_info = {"id": None, "ip_address": ip_address}
135155

136156
try:
137-
user_info["id"] = current_user.get_id()
157+
user_info["id"] = user.get_id()
138158
# TODO: more configurable user attrs here
139159
except AttributeError:
140160
# might happen if:

0 commit comments

Comments
 (0)