Skip to content

Commit 49fc969

Browse files
authored
fix(aci): handle fake alert rule ids in AlertRuleDetector lookup (#104031)
When looking up a Detector via alert rule id, it's possible that there is no corresponding row in the AlertRuleDetector table. We then assume that the alert rule id that was passed is a fake id, so we can use get_object_id_from_fake_id() to get the detector.
1 parent 41df9ad commit 49fc969

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
lines changed

src/sentry/workflow_engine/endpoints/organization_alertrule_detector_index.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
RESPONSE_UNAUTHORIZED,
1717
)
1818
from sentry.apidocs.parameters import GlobalParams
19+
from sentry.incidents.endpoints.serializers.utils import get_object_id_from_fake_id
1920
from sentry.models.organization import Organization
2021
from sentry.workflow_engine.endpoints.serializers.alertrule_detector_serializer import (
2122
AlertRuleDetectorSerializer,
@@ -24,6 +25,7 @@
2425
AlertRuleDetectorValidator,
2526
)
2627
from sentry.workflow_engine.models.alertrule_detector import AlertRuleDetector
28+
from sentry.workflow_engine.models.detector import Detector
2729

2830

2931
@region_silo_endpoint
@@ -69,7 +71,28 @@ def get(self, request: Request, organization: Organization) -> Response:
6971
queryset = queryset.filter(rule_id=rule_id)
7072

7173
alert_rule_detector = queryset.first()
72-
if not alert_rule_detector:
73-
raise ResourceDoesNotExist
7474

75-
return Response(serialize(alert_rule_detector, request.user))
75+
if alert_rule_detector:
76+
return Response(serialize(alert_rule_detector, request.user))
77+
78+
# Fallback: if alert_rule_id was provided but no AlertRuleDetector was found,
79+
# try looking up Detector directly using calculated detector_id
80+
if alert_rule_id:
81+
try:
82+
calculated_detector_id = get_object_id_from_fake_id(int(alert_rule_id))
83+
detector = Detector.objects.get(
84+
id=calculated_detector_id, project__organization=organization
85+
)
86+
87+
if detector:
88+
return Response(
89+
{
90+
"detectorId": str(detector.id),
91+
"alertRuleId": str(alert_rule_id),
92+
"ruleId": None,
93+
}
94+
)
95+
except (ValueError, Detector.DoesNotExist):
96+
pass
97+
98+
raise ResourceDoesNotExist

tests/sentry/workflow_engine/endpoints/test_organization_alertrule_detector.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from sentry.api.serializers import serialize
2+
from sentry.incidents.endpoints.serializers.utils import get_fake_id_from_object_id
23
from sentry.testutils.cases import APITestCase
34
from sentry.testutils.silo import region_silo_test
45

@@ -89,3 +90,33 @@ def test_organization_isolation(self) -> None:
8990

9091
def test_get_without_any_filter(self) -> None:
9192
self.get_error_response(self.organization.slug, status_code=400)
93+
94+
def test_fallback_with_fake_alert_rule_id(self) -> None:
95+
"""
96+
Test that when an alert rule doesn't exist, the endpoint falls back to looking up
97+
the Detector by subtracting 10^9 from the alert_rule_id.
98+
"""
99+
# Create a detector with no AlertRuleDetector mapping
100+
detector = self.create_detector(project=self.project)
101+
102+
# Calculate the fake alert_rule_id
103+
fake_alert_rule_id = get_fake_id_from_object_id(detector.id)
104+
105+
# Query using the fake alert_rule_id
106+
response = self.get_success_response(
107+
self.organization.slug, alert_rule_id=str(fake_alert_rule_id)
108+
)
109+
110+
# Should return a fake AlertRuleDetector response
111+
assert response.data == {
112+
"detectorId": str(detector.id),
113+
"alertRuleId": str(fake_alert_rule_id),
114+
"ruleId": None,
115+
}
116+
117+
def test_fallback_with_nonexistent_detector(self) -> None:
118+
# Use a fake alert_rule_id that won't map to any real detector
119+
nonexistent_fake_id = get_fake_id_from_object_id(999999)
120+
self.get_error_response(
121+
self.organization.slug, alert_rule_id=str(nonexistent_fake_id), status_code=404
122+
)

0 commit comments

Comments
 (0)