diff --git a/src/sentry/integrations/github/webhook.py b/src/sentry/integrations/github/webhook.py index 7bee3f156b98..e955794f2579 100644 --- a/src/sentry/integrations/github/webhook.py +++ b/src/sentry/integrations/github/webhook.py @@ -14,6 +14,7 @@ from django.views.decorators.csrf import csrf_exempt from django.views.generic import View from rest_framework.request import Request +from sentry_sdk import configure_scope from sentry import options from sentry.constants import ObjectStatus @@ -30,12 +31,26 @@ from sentry.shared_integrations.exceptions import ApiError from sentry.utils import json from sentry.utils.json import JSONData +from sentry.utils.sdk import report_tags_already_set from .repository import GitHubRepositoryProvider logger = logging.getLogger("sentry.webhooks") +def clear_tags_and_context_if_already_set() -> None: + with configure_scope() as scope: + report_tags_already_set(scope) + for tag in ["organization", "organization.slug"]: + if tag in scope._tags: + del scope._tags[tag] + + if "organization" in scope._contexts: + del scope._contexts["organization"] + + logger.info("We've reset the context and tags.") + + class Webhook: provider = "github" @@ -456,6 +471,7 @@ def get_secret(self) -> str | None: raise NotImplementedError def handle(self, request: Request) -> HttpResponse: + clear_tags_and_context_if_already_set() secret = self.get_secret() if secret is None: diff --git a/src/sentry/utils/sdk.py b/src/sentry/utils/sdk.py index 8bd776fe7039..3dd229933904 100644 --- a/src/sentry/utils/sdk.py +++ b/src/sentry/utils/sdk.py @@ -1,5 +1,6 @@ import copy import inspect +import logging import random import sentry_sdk @@ -8,7 +9,13 @@ # Reexport sentry_sdk just in case we ever have to write another shim like we # did for raven -from sentry_sdk import capture_exception, capture_message, configure_scope, push_scope # NOQA +from sentry_sdk import ( # NOQA + Scope, + capture_exception, + capture_message, + configure_scope, + push_scope, +) from sentry_sdk.client import get_options from sentry_sdk.transport import make_transport from sentry_sdk.utils import logger as sdk_logger @@ -18,6 +25,8 @@ from sentry.utils.db import DjangoAtomicIntegration from sentry.utils.rust import RustInfoIntegration +logger = logging.getLogger(__name__) + UNSAFE_FILES = ( "sentry/event_manager.py", "sentry/tasks/process_buffer.py", @@ -445,11 +454,27 @@ def _kwargs_into_scope(self, scope, extra=None, tags=None, fingerprint=None, req scope.fingerprint = fingerprint +# We have some events being tagged with organization.slug even when we don't have such info +def report_tags_already_set(scope: Scope): + """If the tags are already set, report them as a Sentry error.""" + try: + + if scope._tags != {}: + for tag in ["organization", "organization.slug"]: + if tag in scope._tags: + logger.info(f"Tags already set: {scope._tags}") + raise Exception("Tags are already set. Code execution will not be affected.") + except Exception as e: + logger.exception(e) + + def bind_organization_context(organization): helper = settings.SENTRY_ORGANIZATION_CONTEXT_HELPER # XXX(dcramer): this is duplicated in organizationContext.jsx on the frontend with sentry_sdk.configure_scope() as scope: + report_tags_already_set(scope) + scope.set_tag("organization", organization.id) scope.set_tag("organization.slug", organization.slug) scope.set_context("organization", {"id": organization.id, "slug": organization.slug})