11import logging
2+ from http import HTTPStatus
23
34import falcon
45import falcon .testing
@@ -228,22 +229,45 @@ def on_get(self, req, resp):
228229 assert " by zero" in event ["exception" ]["values" ][0 ]["value" ]
229230
230231
232+ @pytest .mark .parametrize (
233+ "status" ,
234+ [
235+ falcon .HTTP_502 ,
236+ pytest .param (
237+ 502 ,
238+ marks = pytest .mark .skipif (
239+ (FALCON_VERSION or ()) < (4 ,),
240+ reason = "Integer HTTPError statuses require Falcon 4+" ,
241+ ),
242+ ),
243+ pytest .param (
244+ HTTPStatus .BAD_GATEWAY ,
245+ id = "HTTPStatus.BAD_GATEWAY" ,
246+ marks = pytest .mark .skipif (
247+ (FALCON_VERSION or ()) < (4 ,),
248+ reason = "Integer HTTPError statuses require Falcon 4+" ,
249+ ),
250+ ),
251+ ],
252+ )
231253@pytest .mark .parametrize ("span_streaming" , [True , False ])
232254def test_raised_5xx_errors (
233255 sentry_init ,
234256 capture_exceptions ,
235257 capture_events ,
236258 capture_items ,
237259 span_streaming ,
260+ status ,
238261):
262+ """String, integer, and http.HTTPStatus 5xx HTTPError statuses should be captured."""
239263 sentry_init (
240264 integrations = [FalconIntegration ()],
241265 trace_lifecycle = "stream" if span_streaming else "static" ,
242266 )
243267
244268 class Resource :
245269 def on_get (self , req , resp ):
246- raise falcon .HTTPError (falcon . HTTP_502 )
270+ raise falcon .HTTPError (status )
247271
248272 app = falcon .API ()
249273 app .add_route ("/" , Resource ())
@@ -273,22 +297,45 @@ def on_get(self, req, resp):
273297 assert event ["exception" ]["values" ][0 ]["type" ] == "HTTPError"
274298
275299
300+ @pytest .mark .parametrize (
301+ "status" ,
302+ [
303+ falcon .HTTP_400 ,
304+ pytest .param (
305+ 400 ,
306+ marks = pytest .mark .skipif (
307+ (FALCON_VERSION or ()) < (4 ,),
308+ reason = "Integer HTTPError statuses require Falcon 4+" ,
309+ ),
310+ ),
311+ pytest .param (
312+ HTTPStatus .BAD_REQUEST ,
313+ id = "HTTPStatus.BAD_REQUEST" ,
314+ marks = pytest .mark .skipif (
315+ (FALCON_VERSION or ()) < (4 ,),
316+ reason = "Integer HTTPError statuses require Falcon 4+" ,
317+ ),
318+ ),
319+ ],
320+ )
276321@pytest .mark .parametrize ("span_streaming" , [True , False ])
277322def test_raised_4xx_errors (
278323 sentry_init ,
279324 capture_exceptions ,
280325 capture_events ,
281326 capture_items ,
282327 span_streaming ,
328+ status ,
283329):
330+ """String, integer, and http.HTTPStatus 4xx HTTPError statuses should not be captured."""
284331 sentry_init (
285332 integrations = [FalconIntegration ()],
286333 trace_lifecycle = "stream" if span_streaming else "static" ,
287334 )
288335
289336 class Resource :
290337 def on_get (self , req , resp ):
291- raise falcon .HTTPError (falcon . HTTP_400 )
338+ raise falcon .HTTPError (status )
292339
293340 app = falcon .API ()
294341 app .add_route ("/" , Resource ())
@@ -306,26 +353,45 @@ def on_get(self, req, resp):
306353 assert len (events ) == 0
307354
308355
356+ @pytest .mark .parametrize (
357+ "status" ,
358+ [
359+ falcon .HTTP_508 ,
360+ pytest .param (
361+ 508 ,
362+ marks = pytest .mark .skipif (
363+ (FALCON_VERSION or ()) < (4 ,),
364+ reason = "Integer HTTPStatus statuses require Falcon 4+" ,
365+ ),
366+ ),
367+ pytest .param (
368+ HTTPStatus .LOOP_DETECTED ,
369+ id = "HTTPStatus.LOOP_DETECTED" ,
370+ marks = pytest .mark .skipif (
371+ (FALCON_VERSION or ()) < (4 ,),
372+ reason = "Integer HTTPStatus statuses require Falcon 4+" ,
373+ ),
374+ ),
375+ ],
376+ )
309377@pytest .mark .parametrize ("span_streaming" , [True , False ])
310378def test_http_status (
311379 sentry_init ,
312380 capture_exceptions ,
313381 capture_events ,
314382 capture_items ,
315383 span_streaming ,
384+ status ,
316385):
317- """
318- This just demonstrates, that if Falcon raises a HTTPStatus with code 500
319- (instead of a HTTPError with code 500) Sentry will not capture it.
320- """
386+ """String, integer, and http.HTTPStatus 5xx falcon.HTTPStatus exceptions are not captured."""
321387 sentry_init (
322388 integrations = [FalconIntegration ()],
323389 trace_lifecycle = "stream" if span_streaming else "static" ,
324390 )
325391
326392 class Resource :
327393 def on_get (self , req , resp ):
328- raise falcon .http_status .HTTPStatus (falcon . HTTP_508 )
394+ raise falcon .http_status .HTTPStatus (status )
329395
330396 app = falcon .API ()
331397 app .add_route ("/" , Resource ())
@@ -346,6 +412,58 @@ def on_get(self, req, resp):
346412 assert len (events ) == 0
347413
348414
415+ @pytest .mark .skipif (
416+ (FALCON_VERSION or ()) < (3 ,),
417+ reason = "Integer Response.status values require Falcon 3+" ,
418+ )
419+ @pytest .mark .parametrize (
420+ "status" ,
421+ [
422+ 400 ,
423+ pytest .param (HTTPStatus .BAD_REQUEST , id = "HTTPStatus.BAD_REQUEST" ),
424+ 499 ,
425+ 500 ,
426+ pytest .param (
427+ HTTPStatus .INTERNAL_SERVER_ERROR , id = "HTTPStatus.INTERNAL_SERVER_ERROR"
428+ ),
429+ 599 ,
430+ 600 ,
431+ ],
432+ )
433+ @pytest .mark .parametrize ("span_streaming" , [True , False ])
434+ def test_integer_response_status (sentry_init , capture_events , status , span_streaming ):
435+ """A handler's integer or HTTPStatus response status should capture only 5xx errors."""
436+ sentry_init (
437+ integrations = [FalconIntegration ()],
438+ trace_lifecycle = "stream" if span_streaming else "static" ,
439+ )
440+
441+ class Resource :
442+ def on_get (self , req , resp ):
443+ raise ValueError ("handled error" )
444+
445+ def error_handler (req , resp , ex , params ):
446+ resp .status = status
447+
448+ app = falcon .API ()
449+ app .add_route ("/" , Resource ())
450+ app .add_error_handler (ValueError , error_handler )
451+ events = capture_events ()
452+
453+ response = falcon .testing .TestClient (app ).simulate_get ("/" )
454+
455+ # this exists in falcon >= 3
456+ assert response .status_code == status
457+ if 500 <= status < 600 :
458+ (event ,) = events
459+ exception = event ["exception" ]["values" ][- 1 ]
460+ assert exception ["type" ] == "ValueError"
461+ assert exception ["value" ] == "handled error"
462+ assert exception ["mechanism" ] == {"type" : "falcon" , "handled" : False }
463+ else :
464+ assert not events
465+
466+
349467@pytest .mark .parametrize ("max_value_length" , [1024 , None ])
350468@pytest .mark .parametrize ("span_streaming" , [True , False ])
351469def test_falcon_large_json_request (
0 commit comments