1
1
import json
2
+ import sys
2
3
3
- from sentry_sdk .hub import _should_send_default_pii
4
+ import sentry_sdk
5
+ from sentry_sdk .hub import _internal_exceptions , _should_send_default_pii
4
6
from sentry_sdk .event import AnnotatedValue
7
+ from sentry_sdk ._compat import reraise , implements_iterator
5
8
6
9
7
10
def get_environ (environ ):
@@ -38,28 +41,11 @@ def __init__(self, request):
38
41
self .request = request
39
42
40
43
def extract_into_event (self , event , client_options ):
41
- if "request" in event :
42
- return
43
-
44
- # if the code below fails halfway through we at least have some data
45
- event ["request" ] = request_info = {}
46
-
44
+ request_info = event .setdefault ("request" , {})
47
45
request_info ["url" ] = self .url
48
- request_info ["query_string" ] = self .query_string
49
- request_info ["method" ] = self .method
50
-
51
- request_info ["env" ] = dict (get_environ (self .env ))
52
46
53
47
if _should_send_default_pii ():
54
- request_info ["headers" ] = dict (self .headers )
55
48
request_info ["cookies" ] = dict (self .cookies )
56
- else :
57
- request_info ["headers" ] = {
58
- k : v
59
- for k , v in dict (self .headers ).items ()
60
- if k .lower ().replace ("_" , "-" )
61
- not in ("set-cookie" , "cookie" , "authentication" )
62
- }
63
49
64
50
bodies = client_options .get ("request_bodies" )
65
51
if (
@@ -108,22 +94,6 @@ def content_length(self):
108
94
def url (self ):
109
95
raise NotImplementedError ()
110
96
111
- @property
112
- def query_string (self ):
113
- return self .env .get ("QUERY_STRING" )
114
-
115
- @property
116
- def method (self ):
117
- return self .env .get ("REQUEST_METHOD" )
118
-
119
- @property
120
- def headers (self ):
121
- return get_headers (self .env )
122
-
123
- @property
124
- def env (self ):
125
- raise NotImplementedError ()
126
-
127
97
@property
128
98
def cookies (self ):
129
99
raise NotImplementedError ()
@@ -136,10 +106,6 @@ def raw_data(self):
136
106
def form (self ):
137
107
raise NotImplementedError ()
138
108
139
- @property
140
- def form_is_multipart (self ):
141
- return self .env .get ("CONTENT_TYPE" ).startswith ("multipart/form-data" )
142
-
143
109
@property
144
110
def is_json (self ):
145
111
mt = (self .env .get ("CONTENT_TYPE" ) or "" ).split (";" , 1 )[0 ]
@@ -177,3 +143,89 @@ def get_client_ip(environ):
177
143
return environ ["HTTP_X_FORWARDED_FOR" ].split ("," )[0 ].strip ()
178
144
except (KeyError , IndexError ):
179
145
return environ .get ("REMOTE_ADDR" )
146
+
147
+
148
+ def run_wsgi_app (app , environ , start_response ):
149
+ hub = sentry_sdk .get_current_hub ()
150
+ hub .push_scope ()
151
+ with _internal_exceptions ():
152
+ client_options = sentry_sdk .get_current_hub ().client .options
153
+ sentry_sdk .get_current_hub ().add_event_processor (
154
+ lambda : _make_wsgi_event_processor (environ , client_options )
155
+ )
156
+
157
+ try :
158
+ rv = app (environ , start_response )
159
+ except Exception :
160
+ einfo = sys .exc_info ()
161
+ sentry_sdk .capture_exception (einfo )
162
+ hub .pop_scope_unsafe ()
163
+ reraise (* einfo )
164
+
165
+ return _ScopePoppingResponse (hub , rv )
166
+
167
+
168
+ @implements_iterator
169
+ class _ScopePoppingResponse (object ):
170
+ __slots__ = ("_response" , "_hub" )
171
+
172
+ def __init__ (self , hub , response ):
173
+ self ._hub = hub
174
+ self ._response = response
175
+
176
+ def __iter__ (self ):
177
+ try :
178
+ self ._response = iter (self ._response )
179
+ except Exception :
180
+ einfo = sys .exc_info ()
181
+ sentry_sdk .capture_exception (einfo )
182
+ reraise (* einfo )
183
+ return self
184
+
185
+ def __next__ (self ):
186
+ try :
187
+ return next (self ._response )
188
+ except StopIteration :
189
+ raise
190
+ except Exception :
191
+ einfo = sys .exc_info ()
192
+ sentry_sdk .capture_exception (einfo )
193
+ reraise (* einfo )
194
+
195
+ def close (self ):
196
+ self ._hub .pop_scope_unsafe ()
197
+ if hasattr (self ._response , "close" ):
198
+ try :
199
+ self ._response .close ()
200
+ except Exception :
201
+ einfo = sys .exc_info ()
202
+ sentry_sdk .capture_exception (einfo )
203
+ reraise (* einfo )
204
+
205
+
206
+ def _make_wsgi_event_processor (environ , client_options ):
207
+ def event_processor (event ):
208
+ with _internal_exceptions ():
209
+ # if the code below fails halfway through we at least have some data
210
+ request_info = event .setdefault ("request" , {})
211
+
212
+ if "query_string" not in request_info :
213
+ request_info ["query_string" ] = environ .get ("QUERY_STRING" )
214
+
215
+ if "method" not in request_info :
216
+ request_info ["method" ] = environ .get ("REQUEST_METHOD" )
217
+
218
+ if "env" not in request_info :
219
+ request_info ["env" ] = dict (get_environ (environ ))
220
+
221
+ if "headers" not in request_info :
222
+ request_info ["headers" ] = dict (get_headers (environ ))
223
+ if not _should_send_default_pii ():
224
+ request_info ["headers" ] = {
225
+ k : v
226
+ for k , v in request_info ["headers" ].items ()
227
+ if k .lower ().replace ("_" , "-" )
228
+ not in ("set-cookie" , "cookie" , "authorization" )
229
+ }
230
+
231
+ return event_processor
0 commit comments