Skip to content

Commit 5a99c97

Browse files
committed
Merge branch 'master' of github.com:getsentry/sentry-python into txiao/feat/continuous-profiling-lifecycle
2 parents 1db0411 + d670a15 commit 5a99c97

File tree

12 files changed

+157
-35
lines changed

12 files changed

+157
-35
lines changed

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
steps:
2121
- name: Get auth token
2222
id: token
23-
uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1
23+
uses: actions/create-github-app-token@136412a57a7081aa63c935a2cc2918f76c34f514 # v1.11.2
2424
with:
2525
app-id: ${{ vars.SENTRY_RELEASE_BOT_CLIENT_ID }}
2626
private-key: ${{ secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY }}

sentry_sdk/integrations/grpc/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def _wrap_channel_async(func: Callable[P, AsyncChannel]) -> Callable[P, AsyncCha
8181
"Wrapper for asynchronous secure and insecure channel."
8282

8383
@wraps(func)
84-
def patched_channel(
84+
def patched_channel( # type: ignore
8585
*args: P.args,
8686
interceptors: Optional[Sequence[grpc.aio.ClientInterceptor]] = None,
8787
**kwargs: P.kwargs,
@@ -100,7 +100,7 @@ def _wrap_sync_server(func: Callable[P, Server]) -> Callable[P, Server]:
100100
"""Wrapper for synchronous server."""
101101

102102
@wraps(func)
103-
def patched_server(
103+
def patched_server( # type: ignore
104104
*args: P.args,
105105
interceptors: Optional[Sequence[grpc.ServerInterceptor]] = None,
106106
**kwargs: P.kwargs,
@@ -121,7 +121,7 @@ def _wrap_async_server(func: Callable[P, AsyncServer]) -> Callable[P, AsyncServe
121121
"""Wrapper for asynchronous server."""
122122

123123
@wraps(func)
124-
def patched_aio_server(
124+
def patched_aio_server( # type: ignore
125125
*args: P.args,
126126
interceptors: Optional[Sequence[grpc.ServerInterceptor]] = None,
127127
**kwargs: P.kwargs,

sentry_sdk/integrations/litestar.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
from collections.abc import Set
12
import sentry_sdk
23
from sentry_sdk.consts import OP
3-
from sentry_sdk.integrations import DidNotEnable, Integration
4+
from sentry_sdk.integrations import (
5+
_DEFAULT_FAILED_REQUEST_STATUS_CODES,
6+
DidNotEnable,
7+
Integration,
8+
)
49
from sentry_sdk.integrations.asgi import SentryAsgiMiddleware
510
from sentry_sdk.integrations.logging import ignore_logger
611
from sentry_sdk.scope import should_send_default_pii
@@ -17,6 +22,7 @@
1722
from litestar.middleware import DefineMiddleware # type: ignore
1823
from litestar.routes.http import HTTPRoute # type: ignore
1924
from litestar.data_extractors import ConnectionDataExtractor # type: ignore
25+
from litestar.exceptions import HTTPException # type: ignore
2026
except ImportError:
2127
raise DidNotEnable("Litestar is not installed")
2228

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

54+
def __init__(
55+
self,
56+
failed_request_status_codes=_DEFAULT_FAILED_REQUEST_STATUS_CODES, # type: Set[int]
57+
) -> None:
58+
self.failed_request_status_codes = failed_request_status_codes
59+
4860
@staticmethod
4961
def setup_once():
5062
# type: () -> None
@@ -277,6 +289,14 @@ def exception_handler(exc, scope):
277289
sentry_scope = sentry_sdk.get_isolation_scope()
278290
sentry_scope.set_user(user_info)
279291

292+
if isinstance(exc, HTTPException):
293+
integration = sentry_sdk.get_client().get_integration(LitestarIntegration)
294+
if (
295+
integration is not None
296+
and exc.status_code not in integration.failed_request_status_codes
297+
):
298+
return
299+
280300
event, hint = event_from_exception(
281301
exc,
282302
client_options=sentry_sdk.get_client().options,

sentry_sdk/integrations/socket.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,19 @@ def setup_once():
2727

2828

2929
def _get_span_description(host, port):
30-
# type: (Union[bytes, str, None], Union[str, int, None]) -> str
30+
# type: (Union[bytes, str, None], Union[bytes, str, int, None]) -> str
3131

3232
try:
3333
host = host.decode() # type: ignore
3434
except (UnicodeDecodeError, AttributeError):
3535
pass
3636

37-
description = "%s:%s" % (host, port) # type: ignore
37+
try:
38+
port = port.decode() # type: ignore
39+
except (UnicodeDecodeError, AttributeError):
40+
pass
3841

42+
description = "%s:%s" % (host, port) # type: ignore
3943
return description
4044

4145

@@ -74,7 +78,7 @@ def _patch_getaddrinfo():
7478
real_getaddrinfo = socket.getaddrinfo
7579

7680
def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0):
77-
# type: (Union[bytes, str, None], Union[str, int, None], int, int, int, int) -> List[Tuple[AddressFamily, SocketKind, int, str, Union[Tuple[str, int], Tuple[str, int, int, int]]]]
81+
# type: (Union[bytes, str, None], Union[bytes, str, int, None], int, int, int, int) -> List[Tuple[AddressFamily, SocketKind, int, str, Union[Tuple[str, int], Tuple[str, int, int, int], Tuple[int, bytes]]]]
7882
integration = sentry_sdk.get_client().get_integration(SocketIntegration)
7983
if integration is None:
8084
return real_getaddrinfo(host, port, family, type, proto, flags)
@@ -89,4 +93,4 @@ def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0):
8993

9094
return real_getaddrinfo(host, port, family, type, proto, flags)
9195

92-
socket.getaddrinfo = getaddrinfo # type: ignore
96+
socket.getaddrinfo = getaddrinfo

sentry_sdk/integrations/tornado.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ async def sentry_execute_request_handler(self, *args, **kwargs):
7979
else:
8080

8181
@coroutine # type: ignore
82-
def sentry_execute_request_handler(self, *args, **kwargs):
82+
def sentry_execute_request_handler(self, *args, **kwargs): # type: ignore
8383
# type: (RequestHandler, *Any, **Any) -> Any
8484
with _handle_request_impl(self):
8585
result = yield from old_execute(self, *args, **kwargs)

sentry_sdk/tracing.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
is_valid_sample_rate,
1515
logger,
1616
nanosecond_time,
17+
should_be_treated_as_error,
1718
)
1819

1920
from typing import TYPE_CHECKING
@@ -378,7 +379,7 @@ def __enter__(self):
378379

379380
def __exit__(self, ty, value, tb):
380381
# type: (Optional[Any], Optional[Any], Optional[Any]) -> None
381-
if value is not None:
382+
if value is not None and should_be_treated_as_error(ty, value):
382383
self.set_status(SPANSTATUS.INTERNAL_ERROR)
383384

384385
scope, old_span = self._context_manager_state

sentry_sdk/utils.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,3 +1879,12 @@ def get_current_thread_meta(thread=None):
18791879

18801880
# we've tried everything, time to give up
18811881
return None, None
1882+
1883+
1884+
def should_be_treated_as_error(ty, value):
1885+
# type: (Any, Any) -> bool
1886+
if ty == SystemExit and hasattr(value, "code") and value.code in (0, None):
1887+
# https://docs.python.org/3/library/exceptions.html#SystemExit
1888+
return False
1889+
1890+
return True

tests/integrations/conftest.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,24 @@ def capture_event_scope(self, event, hint=None, scope=None):
3232
return errors
3333

3434
return inner
35+
36+
37+
parametrize_test_configurable_status_codes = pytest.mark.parametrize(
38+
("failed_request_status_codes", "status_code", "expected_error"),
39+
(
40+
(None, 500, True),
41+
(None, 400, False),
42+
({500, 501}, 500, True),
43+
({500, 501}, 401, False),
44+
({*range(400, 500)}, 401, True),
45+
({*range(400, 500)}, 500, False),
46+
({*range(400, 600)}, 300, False),
47+
({*range(400, 600)}, 403, True),
48+
({*range(400, 600)}, 503, True),
49+
({*range(400, 403), 500, 501}, 401, True),
50+
({*range(400, 403), 500, 501}, 405, False),
51+
({*range(400, 403), 500, 501}, 501, True),
52+
({*range(400, 403), 500, 501}, 503, False),
53+
(set(), 500, False),
54+
),
55+
)

tests/integrations/fastapi/test_fastapi.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
FASTAPI_VERSION = parse_version(fastapi.__version__)
2121

22+
from tests.integrations.conftest import parametrize_test_configurable_status_codes
2223
from tests.integrations.starlette import test_starlette
2324

2425

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

652653

653-
@test_starlette.parametrize_test_configurable_status_codes
654+
@parametrize_test_configurable_status_codes
654655
def test_configurable_status_codes(
655656
sentry_init,
656657
capture_events,

tests/integrations/litestar/test_litestar.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22
import functools
33

4+
from litestar.exceptions import HTTPException
45
import pytest
56

67
from sentry_sdk import capture_message
@@ -16,6 +17,8 @@
1617
from litestar.middleware.session.server_side import ServerSideSessionConfig
1718
from litestar.testing import TestClient
1819

20+
from tests.integrations.conftest import parametrize_test_configurable_status_codes
21+
1922

2023
def litestar_app_factory(middleware=None, debug=True, exception_handlers=None):
2124
class MyController(Controller):
@@ -396,3 +399,31 @@ async def __call__(self, scope, receive, send):
396399
}
397400
else:
398401
assert "user" not in event
402+
403+
404+
@parametrize_test_configurable_status_codes
405+
def test_configurable_status_codes(
406+
sentry_init,
407+
capture_events,
408+
failed_request_status_codes,
409+
status_code,
410+
expected_error,
411+
):
412+
integration_kwargs = (
413+
{"failed_request_status_codes": failed_request_status_codes}
414+
if failed_request_status_codes is not None
415+
else {}
416+
)
417+
sentry_init(integrations=[LitestarIntegration(**integration_kwargs)])
418+
419+
events = capture_events()
420+
421+
@get("/error")
422+
async def error() -> None:
423+
raise HTTPException(status_code=status_code)
424+
425+
app = Litestar([error])
426+
client = TestClient(app)
427+
client.get("/error")
428+
429+
assert len(events) == int(expected_error)

0 commit comments

Comments
 (0)