summaryrefslogtreecommitdiffstats
path: root/third_party/python/sentry-sdk/sentry_sdk/integrations/threading.py
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/python/sentry-sdk/sentry_sdk/integrations/threading.py
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/python/sentry-sdk/sentry_sdk/integrations/threading.py')
-rw-r--r--third_party/python/sentry-sdk/sentry_sdk/integrations/threading.py90
1 files changed, 90 insertions, 0 deletions
diff --git a/third_party/python/sentry-sdk/sentry_sdk/integrations/threading.py b/third_party/python/sentry-sdk/sentry_sdk/integrations/threading.py
new file mode 100644
index 0000000000..b750257e2a
--- /dev/null
+++ b/third_party/python/sentry-sdk/sentry_sdk/integrations/threading.py
@@ -0,0 +1,90 @@
+from __future__ import absolute_import
+
+import sys
+from threading import Thread, current_thread
+
+from sentry_sdk import Hub
+from sentry_sdk._compat import reraise
+from sentry_sdk._types import MYPY
+from sentry_sdk.integrations import Integration
+from sentry_sdk.utils import event_from_exception, capture_internal_exceptions
+
+if MYPY:
+ from typing import Any
+ from typing import TypeVar
+ from typing import Callable
+ from typing import Optional
+
+ from sentry_sdk._types import ExcInfo
+
+ F = TypeVar("F", bound=Callable[..., Any])
+
+
+class ThreadingIntegration(Integration):
+ identifier = "threading"
+
+ def __init__(self, propagate_hub=False):
+ # type: (bool) -> None
+ self.propagate_hub = propagate_hub
+
+ @staticmethod
+ def setup_once():
+ # type: () -> None
+ old_start = Thread.start
+
+ def sentry_start(self, *a, **kw):
+ # type: (Thread, *Any, **Any) -> Any
+ hub = Hub.current
+ integration = hub.get_integration(ThreadingIntegration)
+ if integration is not None:
+ if not integration.propagate_hub:
+ hub_ = None
+ else:
+ hub_ = Hub(hub)
+ # Patching instance methods in `start()` creates a reference cycle if
+ # done in a naive way. See
+ # https://github.com/getsentry/sentry-python/pull/434
+ #
+ # In threading module, using current_thread API will access current thread instance
+ # without holding it to avoid a reference cycle in an easier way.
+ with capture_internal_exceptions():
+ new_run = _wrap_run(hub_, getattr(self.run, "__func__", self.run))
+ self.run = new_run # type: ignore
+
+ return old_start(self, *a, **kw) # type: ignore
+
+ Thread.start = sentry_start # type: ignore
+
+
+def _wrap_run(parent_hub, old_run_func):
+ # type: (Optional[Hub], F) -> F
+ def run(*a, **kw):
+ # type: (*Any, **Any) -> Any
+ hub = parent_hub or Hub.current
+ with hub:
+ try:
+ self = current_thread()
+ return old_run_func(self, *a, **kw)
+ except Exception:
+ reraise(*_capture_exception())
+
+ return run # type: ignore
+
+
+def _capture_exception():
+ # type: () -> ExcInfo
+ hub = Hub.current
+ exc_info = sys.exc_info()
+
+ if hub.get_integration(ThreadingIntegration) is not None:
+ # If an integration is there, a client has to be there.
+ client = hub.client # type: Any
+
+ event, hint = event_from_exception(
+ exc_info,
+ client_options=client.options,
+ mechanism={"type": "threading", "handled": False},
+ )
+ hub.capture_event(event, hint=hint)
+
+ return exc_info