Skip to content

Commit

Permalink
feat(litestar): Add failed_request_status_codes (#4021)
Browse files Browse the repository at this point in the history
  • Loading branch information
vrslev authored Feb 6, 2025
1 parent ab36fc4 commit bc72f78
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 23 deletions.
22 changes: 21 additions & 1 deletion sentry_sdk/integrations/litestar.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
from collections.abc import Set
import sentry_sdk
from sentry_sdk.consts import OP
from sentry_sdk.integrations import DidNotEnable, Integration
from sentry_sdk.integrations import (
_DEFAULT_FAILED_REQUEST_STATUS_CODES,
DidNotEnable,
Integration,
)
from sentry_sdk.integrations.asgi import SentryAsgiMiddleware
from sentry_sdk.integrations.logging import ignore_logger
from sentry_sdk.scope import should_send_default_pii
Expand All @@ -17,6 +22,7 @@
from litestar.middleware import DefineMiddleware # type: ignore
from litestar.routes.http import HTTPRoute # type: ignore
from litestar.data_extractors import ConnectionDataExtractor # type: ignore
from litestar.exceptions import HTTPException # type: ignore
except ImportError:
raise DidNotEnable("Litestar is not installed")

Expand Down Expand Up @@ -45,6 +51,12 @@ class LitestarIntegration(Integration):
identifier = "litestar"
origin = f"auto.http.{identifier}"

def __init__(
self,
failed_request_status_codes=_DEFAULT_FAILED_REQUEST_STATUS_CODES, # type: Set[int]
) -> None:
self.failed_request_status_codes = failed_request_status_codes

@staticmethod
def setup_once():
# type: () -> None
Expand Down Expand Up @@ -277,6 +289,14 @@ def exception_handler(exc, scope):
sentry_scope = sentry_sdk.get_isolation_scope()
sentry_scope.set_user(user_info)

if isinstance(exc, HTTPException):
integration = sentry_sdk.get_client().get_integration(LitestarIntegration)
if (
integration is not None
and exc.status_code not in integration.failed_request_status_codes
):
return

event, hint = event_from_exception(
exc,
client_options=sentry_sdk.get_client().options,
Expand Down
21 changes: 21 additions & 0 deletions tests/integrations/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,24 @@ def capture_event_scope(self, event, hint=None, scope=None):
return errors

return inner


parametrize_test_configurable_status_codes = pytest.mark.parametrize(
("failed_request_status_codes", "status_code", "expected_error"),
(
(None, 500, True),
(None, 400, False),
({500, 501}, 500, True),
({500, 501}, 401, False),
({*range(400, 500)}, 401, True),
({*range(400, 500)}, 500, False),
({*range(400, 600)}, 300, False),
({*range(400, 600)}, 403, True),
({*range(400, 600)}, 503, True),
({*range(400, 403), 500, 501}, 401, True),
({*range(400, 403), 500, 501}, 405, False),
({*range(400, 403), 500, 501}, 501, True),
({*range(400, 403), 500, 501}, 503, False),
(set(), 500, False),
),
)
3 changes: 2 additions & 1 deletion tests/integrations/fastapi/test_fastapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

FASTAPI_VERSION = parse_version(fastapi.__version__)

from tests.integrations.conftest import parametrize_test_configurable_status_codes
from tests.integrations.starlette import test_starlette


Expand Down Expand Up @@ -650,7 +651,7 @@ def test_transaction_http_method_custom(sentry_init, capture_events):
assert event2["request"]["method"] == "HEAD"


@test_starlette.parametrize_test_configurable_status_codes
@parametrize_test_configurable_status_codes
def test_configurable_status_codes(
sentry_init,
capture_events,
Expand Down
31 changes: 31 additions & 0 deletions tests/integrations/litestar/test_litestar.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations
import functools

from litestar.exceptions import HTTPException
import pytest

from sentry_sdk import capture_message
Expand All @@ -16,6 +17,8 @@
from litestar.middleware.session.server_side import ServerSideSessionConfig
from litestar.testing import TestClient

from tests.integrations.conftest import parametrize_test_configurable_status_codes


def litestar_app_factory(middleware=None, debug=True, exception_handlers=None):
class MyController(Controller):
Expand Down Expand Up @@ -396,3 +399,31 @@ async def __call__(self, scope, receive, send):
}
else:
assert "user" not in event


@parametrize_test_configurable_status_codes
def test_configurable_status_codes(
sentry_init,
capture_events,
failed_request_status_codes,
status_code,
expected_error,
):
integration_kwargs = (
{"failed_request_status_codes": failed_request_status_codes}
if failed_request_status_codes is not None
else {}
)
sentry_init(integrations=[LitestarIntegration(**integration_kwargs)])

events = capture_events()

@get("/error")
async def error() -> None:
raise HTTPException(status_code=status_code)

app = Litestar([error])
client = TestClient(app)
client.get("/error")

assert len(events) == int(expected_error)
23 changes: 2 additions & 21 deletions tests/integrations/starlette/test_starlette.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
from starlette.middleware.trustedhost import TrustedHostMiddleware
from starlette.testclient import TestClient

from tests.integrations.conftest import parametrize_test_configurable_status_codes


STARLETTE_VERSION = parse_version(starlette.__version__)

Expand Down Expand Up @@ -1298,27 +1300,6 @@ def test_transaction_http_method_custom(sentry_init, capture_events):
assert event2["request"]["method"] == "HEAD"


parametrize_test_configurable_status_codes = pytest.mark.parametrize(
("failed_request_status_codes", "status_code", "expected_error"),
(
(None, 500, True),
(None, 400, False),
({500, 501}, 500, True),
({500, 501}, 401, False),
({*range(400, 500)}, 401, True),
({*range(400, 500)}, 500, False),
({*range(400, 600)}, 300, False),
({*range(400, 600)}, 403, True),
({*range(400, 600)}, 503, True),
({*range(400, 403), 500, 501}, 401, True),
({*range(400, 403), 500, 501}, 405, False),
({*range(400, 403), 500, 501}, 501, True),
({*range(400, 403), 500, 501}, 503, False),
(set(), 500, False),
),
)


@parametrize_test_configurable_status_codes
def test_configurable_status_codes(
sentry_init,
Expand Down

0 comments on commit bc72f78

Please sign in to comment.