Skip to content

Commit 05432ab

Browse files
authored
feat: Allow integrations to define control flow exceptions (#6425)
### Description Some frameworks we're integrating with use specific exception types for control flow. If we encounter them, we should not set the status of the current span to error. Implement a global ignore list that each integration can populate with control flow exceptions known to it, so that whenever a span finishes, it has access to the list and can decide whether the exception that occurred constitutes an error or not. #### Issues - Closes #6408 - Closes https://linear.app/getsentry/issue/PY-2492 #### Reminders - Please add tests to validate your changes, and lint your code using `tox -e linters`. - Add GH Issue ID _&_ Linear ID (if applicable) - PR title should use [conventional commit](https://develop.sentry.dev/engineering-practices/commit-messages/#type) style (`feat:`, `fix:`, `ref:`, `meta:`) - For external contributors: [CONTRIBUTING.md](https://github.com/getsentry/sentry-python/blob/master/CONTRIBUTING.md), [Sentry SDK development docs](https://develop.sentry.dev/sdk/), [Discord community](https://discord.gg/Ww9hbqr)
1 parent bb3fcb4 commit 05432ab

2 files changed

Lines changed: 16 additions & 9 deletions

File tree

sentry_sdk/integrations/aiohttp.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
HAS_REAL_CONTEXTVARS,
4343
SENSITIVE_DATA_SUBSTITUTE,
4444
AnnotatedValue,
45+
_register_control_flow_exception,
4546
capture_internal_exceptions,
4647
ensure_integration_enabled,
4748
event_from_exception,
@@ -111,6 +112,12 @@ def setup_once() -> None:
111112
" or aiocontextvars package." + CONTEXTVARS_ERROR_MESSAGE
112113
)
113114

115+
# In the aiohttp integration, all of their HTTP responses are Exceptions.
116+
# Because they have to be raised and handled by the framework, we need to
117+
# register the exceptions as control flow exceptions so that we don't
118+
# accidentally overwrite a status of "ok" with "error".
119+
_register_control_flow_exception(HTTPException)
120+
114121
ignore_logger("aiohttp.server")
115122

116123
old_handle = Application._handle

sentry_sdk/utils.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,6 @@
2727
# Python 3.10 and below
2828
BaseExceptionGroup = None # type: ignore
2929

30-
try:
31-
from aiohttp.web_exceptions import HTTPException as AIOHttpHttpException
32-
except ImportError:
33-
AIOHttpHttpException = None
34-
3530
from typing import TYPE_CHECKING
3631

3732
import sentry_sdk
@@ -93,6 +88,10 @@
9388
"is_sentry_internal_task", default=False
9489
)
9590

91+
# These exceptions won't set the span status to error if they occur. Use
92+
# register_control_flow_exception to add to this list
93+
_control_flow_exception_classes: "list[type]" = []
94+
9695

9796
def is_internal_task() -> bool:
9897
return _is_sentry_internal_task.get()
@@ -1983,15 +1982,16 @@ def get_current_thread_meta(
19831982
return None, None
19841983

19851984

1985+
def _register_control_flow_exception(exc_type: type) -> None:
1986+
_control_flow_exception_classes.append(exc_type)
1987+
1988+
19861989
def should_be_treated_as_error(ty: "Any", value: "Any") -> bool:
19871990
if ty == SystemExit and hasattr(value, "code") and value.code in (0, None):
19881991
# https://docs.python.org/3/library/exceptions.html#SystemExit
19891992
return False
19901993

1991-
# In the aiohttp integration, all of their HTTP responses are Exceptions.
1992-
# Because they have to be raised and handled by the framework, we need this check so
1993-
# that we don't accidentally overwrite a status of "ok" with "error" here.
1994-
if AIOHttpHttpException and isinstance(value, AIOHttpHttpException):
1994+
if issubclass(ty, tuple(_control_flow_exception_classes)):
19951995
return False
19961996

19971997
return True

0 commit comments

Comments
 (0)