Skip to content

Commit b9174a1

Browse files
iamrajjoshiandrewshie-sentry
authored andcommitted
🔧 chore(slos): Update Halt to Success for Bot Commands (#81271)
user errors such as: trying to link identity when identity is already linked, unlinking when there was no identity to begin with was currently recorded as a halt, leading to "bad events" in our SLO. Updating these states to success.
1 parent e5a4e34 commit b9174a1

File tree

7 files changed

+29
-51
lines changed

7 files changed

+29
-51
lines changed

Diff for: src/sentry/integrations/discord/webhooks/command.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def help_handler(self, input: CommandInput) -> IntegrationResponse[str]:
8080
def link_user_handler(self, _: CommandInput) -> IntegrationResponse[str]:
8181
if self.request.has_identity():
8282
return IntegrationResponse(
83-
interaction_result=EventLifecycleOutcome.HALTED,
83+
interaction_result=EventLifecycleOutcome.SUCCESS,
8484
response=ALREADY_LINKED_MESSAGE.format(email=self.request.get_identity_str()),
8585
outcome_reason=str(MessageCommandHaltReason.ALREADY_LINKED),
8686
context_data={
@@ -120,7 +120,7 @@ def link_user_handler(self, _: CommandInput) -> IntegrationResponse[str]:
120120
def unlink_user_handler(self, input: CommandInput) -> IntegrationResponse[str]:
121121
if not self.request.has_identity():
122122
return IntegrationResponse(
123-
interaction_result=EventLifecycleOutcome.HALTED,
123+
interaction_result=EventLifecycleOutcome.SUCCESS,
124124
response=NOT_LINKED_MESSAGE,
125125
outcome_reason=str(MessageCommandHaltReason.NOT_LINKED),
126126
)

Diff for: src/sentry/integrations/msteams/webhook.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ def link_user_handler(self, input: CommandInput) -> IntegrationResponse[Adaptive
669669

670670
if has_linked_identity:
671671
return IntegrationResponse(
672-
interaction_result=EventLifecycleOutcome.HALTED,
672+
interaction_result=EventLifecycleOutcome.SUCCESS,
673673
response=build_already_linked_identity_command_card(),
674674
outcome_reason=str(MessageCommandHaltReason.ALREADY_LINKED),
675675
context_data={

Diff for: src/sentry/integrations/slack/webhooks/base.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ def link_user_handler(self, input: CommandInput) -> IntegrationResponse[Response
166166
response = self.endpoint.link_user(self.request)
167167
if ALREADY_LINKED_MESSAGE.format(username=self.request.identity_str) in str(response.data):
168168
return IntegrationResponse(
169-
interaction_result=EventLifecycleOutcome.HALTED,
169+
interaction_result=EventLifecycleOutcome.SUCCESS,
170170
response=response,
171171
outcome_reason=str(MessageCommandHaltReason.ALREADY_LINKED),
172172
context_data={
@@ -182,7 +182,7 @@ def unlink_user_handler(self, input: CommandInput) -> IntegrationResponse[Respon
182182
response = self.endpoint.unlink_user(self.request)
183183
if NOT_LINKED_MESSAGE in str(response.data):
184184
return IntegrationResponse(
185-
interaction_result=EventLifecycleOutcome.HALTED,
185+
interaction_result=EventLifecycleOutcome.SUCCESS,
186186
response=response,
187187
outcome_reason=str(MessageCommandHaltReason.NOT_LINKED),
188188
context_data={
@@ -200,7 +200,7 @@ def link_team_handler(self, input: CommandInput) -> IntegrationResponse[Response
200200
for message, reason in self.TEAM_HALT_MAPPINGS.items():
201201
if message in str(response.data):
202202
return IntegrationResponse(
203-
interaction_result=EventLifecycleOutcome.HALTED,
203+
interaction_result=EventLifecycleOutcome.SUCCESS,
204204
response=response,
205205
outcome_reason=str(reason),
206206
)
@@ -215,7 +215,7 @@ def unlink_team_handler(self, input: CommandInput) -> IntegrationResponse[Respon
215215
for message, reason in self.TEAM_HALT_MAPPINGS.items():
216216
if message in str(response.data):
217217
return IntegrationResponse(
218-
interaction_result=EventLifecycleOutcome.HALTED,
218+
interaction_result=EventLifecycleOutcome.SUCCESS,
219219
response=response,
220220
outcome_reason=str(reason),
221221
)

Diff for: tests/sentry/integrations/discord/webhooks/test_command.py

+6-14
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,10 @@
44
from sentry.integrations.discord.requests.base import DiscordRequestTypes
55
from sentry.integrations.discord.webhooks.command import HELP_MESSAGE, NOT_LINKED_MESSAGE
66
from sentry.integrations.discord.webhooks.types import DiscordResponseTypes
7-
from sentry.integrations.messaging.metrics import (
8-
MessageCommandFailureReason,
9-
MessageCommandHaltReason,
10-
)
7+
from sentry.integrations.messaging.metrics import MessageCommandFailureReason
118
from sentry.integrations.types import EventLifecycleOutcome
129
from sentry.testutils.cases import APITestCase
13-
from tests.sentry.integrations.utils.test_assert_metrics import (
14-
assert_failure_metric,
15-
assert_halt_metric,
16-
)
10+
from tests.sentry.integrations.utils.test_assert_metrics import assert_failure_metric
1711

1812
WEBHOOK_URL = "/extensions/discord/interactions/"
1913

@@ -211,10 +205,9 @@ def test_link_already_linked(self, mock_record):
211205
assert data["data"]["flags"] == EPHEMERAL_FLAG
212206
assert response.status_code == 200
213207

214-
start, halt = mock_record.mock_calls
208+
start, success = mock_record.mock_calls
215209
assert start.args[0] == EventLifecycleOutcome.STARTED
216-
assert halt.args[0] == EventLifecycleOutcome.HALTED
217-
assert_halt_metric(mock_record, MessageCommandHaltReason.ALREADY_LINKED.value)
210+
assert success.args[0] == EventLifecycleOutcome.SUCCESS
218211

219212
@mock.patch("sentry.integrations.utils.metrics.EventLifecycle.record_event")
220213
def test_unlink_no_identity(self, mock_record):
@@ -239,10 +232,9 @@ def test_unlink_no_identity(self, mock_record):
239232
assert data["data"]["flags"] == EPHEMERAL_FLAG
240233
assert response.status_code == 200
241234

242-
start, halt = mock_record.mock_calls
235+
start, success = mock_record.mock_calls
243236
assert start.args[0] == EventLifecycleOutcome.STARTED
244-
assert halt.args[0] == EventLifecycleOutcome.HALTED
245-
assert_halt_metric(mock_record, MessageCommandHaltReason.NOT_LINKED.value)
237+
assert success.args[0] == EventLifecycleOutcome.SUCCESS
246238

247239
@mock.patch("sentry.integrations.utils.metrics.EventLifecycle.record_event")
248240
def test_unlink(self, mock_record):

Diff for: tests/sentry/integrations/msteams/test_webhook.py

+2-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from django.test import override_settings
99
from django.urls import reverse
1010

11-
from sentry.integrations.messaging.metrics import MessageCommandHaltReason
1211
from sentry.integrations.models.integration import Integration
1312
from sentry.integrations.msteams.utils import ACTION_TYPE
1413
from sentry.integrations.types import EventLifecycleOutcome
@@ -17,7 +16,6 @@
1716
from sentry.testutils.silo import assume_test_silo_mode
1817
from sentry.users.models.identity import Identity
1918
from sentry.utils import jwt
20-
from tests.sentry.integrations.utils.test_assert_metrics import assert_halt_metric
2119

2220
from .test_helpers import (
2321
DECODED_TOKEN,
@@ -546,10 +544,9 @@ def test_link_command_already_linked(self, mock_time, mock_decode, mock_record):
546544
)
547545
assert "Bearer my_token" in responses.calls[3].request.headers["Authorization"]
548546

549-
start, halt = mock_record.mock_calls
547+
start, success = mock_record.mock_calls
550548
assert start.args[0] == EventLifecycleOutcome.STARTED
551-
assert halt.args[0] == EventLifecycleOutcome.HALTED
552-
assert_halt_metric(mock_record, MessageCommandHaltReason.ALREADY_LINKED.value)
549+
assert success.args[0] == EventLifecycleOutcome.SUCCESS
553550

554551
@responses.activate
555552
@mock.patch("sentry.utils.jwt.decode")

Diff for: tests/sentry/integrations/slack/webhooks/commands/test_link_team.py

+10-17
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import responses
55
from rest_framework import status
66

7-
from sentry.integrations.messaging.metrics import MessageCommandHaltReason
87
from sentry.integrations.slack.webhooks.command import (
98
CHANNEL_ALREADY_LINKED_MESSAGE,
109
INSUFFICIENT_ROLE_MESSAGE,
@@ -18,7 +17,6 @@
1817
from sentry.testutils.helpers.features import with_feature
1918
from sentry.testutils.silo import assume_test_silo_mode
2019
from tests.sentry.integrations.slack.webhooks.commands import SlackCommandsTest
21-
from tests.sentry.integrations.utils.test_assert_metrics import assert_halt_metric
2220

2321
OTHER_SLACK_ID = "UXXXXXXX2"
2422

@@ -67,10 +65,9 @@ def test_link_another_team_to_channel(self, mock_record):
6765
assert CHANNEL_ALREADY_LINKED_MESSAGE in get_response_text(data)
6866

6967
assert len(mock_record.mock_calls) == 2
70-
start, halt = mock_record.mock_calls
68+
start, success = mock_record.mock_calls
7169
assert start.args[0] == EventLifecycleOutcome.STARTED
72-
assert halt.args[0] == EventLifecycleOutcome.HALTED
73-
assert_halt_metric(mock_record, MessageCommandHaltReason.CHANNEL_ALREADY_LINKED.value)
70+
assert success.args[0] == EventLifecycleOutcome.SUCCESS
7471

7572
@with_feature("organizations:slack-multiple-team-single-channel-linking")
7673
@patch("sentry.integrations.utils.metrics.EventLifecycle.record_event")
@@ -117,10 +114,9 @@ def test_link_team_from_dm(self, mock_record):
117114
data = orjson.loads(response.content)
118115
assert LINK_FROM_CHANNEL_MESSAGE in get_response_text(data)
119116

120-
start, halt = mock_record.mock_calls
117+
start, success = mock_record.mock_calls
121118
assert start.args[0] == EventLifecycleOutcome.STARTED
122-
assert halt.args[0] == EventLifecycleOutcome.HALTED
123-
assert_halt_metric(mock_record, MessageCommandHaltReason.LINK_FROM_CHANNEL.value)
119+
assert success.args[0] == EventLifecycleOutcome.SUCCESS
124120

125121
@responses.activate
126122
@patch("sentry.integrations.utils.metrics.EventLifecycle.record_event")
@@ -134,10 +130,9 @@ def test_link_team_identity_does_not_exist(self, mock_record):
134130
data = self.send_slack_message("link team", user_id=OTHER_SLACK_ID)
135131
assert LINK_USER_FIRST_MESSAGE in get_response_text(data)
136132

137-
start, halt = mock_record.mock_calls
133+
start, success = mock_record.mock_calls
138134
assert start.args[0] == EventLifecycleOutcome.STARTED
139-
assert halt.args[0] == EventLifecycleOutcome.HALTED
140-
assert_halt_metric(mock_record, MessageCommandHaltReason.LINK_USER_FIRST.value)
135+
assert success.args[0] == EventLifecycleOutcome.SUCCESS
141136

142137
@responses.activate
143138
@patch("sentry.integrations.utils.metrics.EventLifecycle.record_event")
@@ -156,10 +151,9 @@ def test_link_team_insufficient_role(self, mock_record):
156151
data = self.send_slack_message("link team", user_id=OTHER_SLACK_ID)
157152
assert INSUFFICIENT_ROLE_MESSAGE in get_response_text(data)
158153

159-
start, halt = mock_record.mock_calls
154+
start, success = mock_record.mock_calls
160155
assert start.args[0] == EventLifecycleOutcome.STARTED
161-
assert halt.args[0] == EventLifecycleOutcome.HALTED
162-
assert_halt_metric(mock_record, MessageCommandHaltReason.INSUFFICIENT_ROLE.value)
156+
assert success.args[0] == EventLifecycleOutcome.SUCCESS
163157

164158
@responses.activate
165159
@patch("sentry.integrations.utils.metrics.EventLifecycle.record_event")
@@ -231,10 +225,9 @@ def test_unlink_no_team(self, mock_record):
231225
)
232226
assert TEAM_NOT_LINKED_MESSAGE in get_response_text(data)
233227

234-
start, halt = mock_record.mock_calls
228+
start, success = mock_record.mock_calls
235229
assert start.args[0] == EventLifecycleOutcome.STARTED
236-
assert halt.args[0] == EventLifecycleOutcome.HALTED
237-
assert_halt_metric(mock_record, MessageCommandHaltReason.TEAM_NOT_LINKED.value)
230+
assert success.args[0] == EventLifecycleOutcome.SUCCESS
238231

239232
@responses.activate
240233
@patch("sentry.integrations.utils.metrics.EventLifecycle.record_event")

Diff for: tests/sentry/integrations/slack/webhooks/commands/test_link_user.py

+4-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from unittest.mock import patch
22

3-
from sentry.integrations.messaging.metrics import MessageCommandHaltReason
43
from sentry.integrations.models.organization_integration import OrganizationIntegration
54
from sentry.integrations.slack.views.link_identity import SUCCESS_LINKED_MESSAGE, build_linking_url
65
from sentry.integrations.slack.views.unlink_identity import (
@@ -13,7 +12,6 @@
1312
from sentry.testutils.silo import control_silo_test
1413
from sentry.users.models.identity import Identity
1514
from tests.sentry.integrations.slack.webhooks.commands import SlackCommandsTest
16-
from tests.sentry.integrations.utils.test_assert_metrics import assert_halt_metric
1715

1816

1917
@control_silo_test
@@ -51,10 +49,9 @@ def test_link_command_already_linked(self, mock_record):
5149
data = self.send_slack_message("link")
5250
assert "You are already linked as" in get_response_text(data)
5351

54-
start, halt = mock_record.mock_calls
52+
start, success = mock_record.mock_calls
5553
assert start.args[0] == EventLifecycleOutcome.STARTED
56-
assert halt.args[0] == EventLifecycleOutcome.HALTED
57-
assert_halt_metric(mock_record, MessageCommandHaltReason.ALREADY_LINKED.value)
54+
assert success.args[0] == EventLifecycleOutcome.SUCCESS
5855

5956

6057
@control_silo_test
@@ -134,7 +131,6 @@ def test_unlink_command_already_unlinked(self, mock_record):
134131
data = self.send_slack_message("unlink")
135132
assert NOT_LINKED_MESSAGE in get_response_text(data)
136133

137-
start, halt = mock_record.mock_calls
134+
start, success = mock_record.mock_calls
138135
assert start.args[0] == EventLifecycleOutcome.STARTED
139-
assert halt.args[0] == EventLifecycleOutcome.HALTED
140-
assert_halt_metric(mock_record, MessageCommandHaltReason.NOT_LINKED.value)
136+
assert success.args[0] == EventLifecycleOutcome.SUCCESS

0 commit comments

Comments
 (0)