1
1
from __future__ import absolute_import
2
2
3
+ import weakref
4
+
3
5
from sentry_sdk import capture_exception , get_current_hub
4
6
from sentry_sdk .hub import _internal_exceptions , _should_send_default_pii
5
7
from ._wsgi import RequestExtractor , run_wsgi_app
6
8
from . import Integration
7
9
8
10
try :
9
- from flask_login import current_user
11
+ from flask_login import current_user as current_user_proxy
10
12
except ImportError :
11
- current_user = None
13
+ current_user_proxy = None
12
14
13
15
from flask import Flask , _request_ctx_stack , _app_ctx_stack
14
16
from flask .signals import (
@@ -43,7 +45,22 @@ def _push_appctx(*args, **kwargs):
43
45
# always want to push scope regardless of whether WSGI app might already
44
46
# have (not the case for CLI for example)
45
47
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
+ )
47
64
48
65
49
66
def _pop_appctx (* args , ** kwargs ):
@@ -54,13 +71,16 @@ def _capture_exception(sender, exception, **kwargs):
54
71
capture_exception (exception )
55
72
56
73
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 ):
60
75
client_options = get_current_hub ().client .options
61
76
62
77
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 :
64
84
if "transaction" not in event :
65
85
try :
66
86
event ["transaction" ] = request .url_rule .endpoint
@@ -72,7 +92,7 @@ def event_processor(event):
72
92
73
93
if _should_send_default_pii ():
74
94
with _internal_exceptions ():
75
- _set_user_info (request , event )
95
+ _set_user_info (request , weak_user (), event )
76
96
77
97
with _internal_exceptions ():
78
98
_process_frames (app , event )
@@ -119,7 +139,7 @@ def size_of_file(self, file):
119
139
return file .content_length
120
140
121
141
122
- def _set_user_info (request , event ):
142
+ def _set_user_info (request , user , event ):
123
143
if "user" in event :
124
144
return
125
145
@@ -134,7 +154,7 @@ def _set_user_info(request, event):
134
154
user_info = {"id" : None , "ip_address" : ip_address }
135
155
136
156
try :
137
- user_info ["id" ] = current_user .get_id ()
157
+ user_info ["id" ] = user .get_id ()
138
158
# TODO: more configurable user attrs here
139
159
except AttributeError :
140
160
# might happen if:
0 commit comments