Browse Source

ref(daily summary): Replace newlines with a space (#67658)

Replace newline characters with a space so errors like this look better:

<img width="265" alt="Screenshot 2024-03-25 at 3 18 27 PM"
src="https://github.com/getsentry/sentry/assets/29959063/d21d7bf9-1756-48b8-85e9-e294592a8ec1">
Colleen O'Rourke 11 months ago
parent
commit
1b7137a5e9

+ 1 - 1
src/sentry/integrations/slack/message_builder/notifications/daily_summary.py

@@ -39,7 +39,7 @@ class SlackDailySummaryMessageBuilder(SlackNotificationsMessageBuilder):
             params={"referrer": self.notification.get_referrer(ExternalProviders.SLACK)}
         )
         title = build_attachment_title(group)
-        attachment_text = self.get_attachment_text(group)
+        attachment_text = self.get_attachment_text(group).replace("\n", " ")
         if not attachment_text:
             return f"<{link}|*{escape_slack_text(title)}*>"
         return f"<{link}|*{escape_slack_text(title)}*>\n{attachment_text}"

+ 54 - 0
tests/sentry/tasks/test_daily_summary.py

@@ -686,6 +686,60 @@ class DailySummaryTest(
         )
         assert "higher than last 14d avg" in blocks[3]["fields"][1]["text"]
 
+    @responses.activate
+    @with_feature("organizations:slack-block-kit")
+    def test_slack_notification_contents_newline(self):
+        type_string = '"""\nTraceback (most recent call last):\nFile /\'/usr/hb/meow/\''
+        data = {
+            "timestamp": iso_format(self.now),
+            "stacktrace": copy.deepcopy(DEFAULT_EVENT_DATA["stacktrace"]),
+            "fingerprint": ["group-5"],
+            "exception": {
+                "values": [
+                    {
+                        "type": "WorkerLostError",
+                        "value": type_string,
+                    }
+                ]
+            },
+        }
+        self.store_event(
+            data=data,
+            project_id=self.project.id,
+            assert_no_errors=False,
+        )
+        self.store_outcomes(
+            {
+                "org_id": self.organization.id,
+                "project_id": self.project.id,
+                "outcome": Outcome.ACCEPTED,
+                "category": DataCategory.ERROR,
+                "timestamp": self.now,
+                "key_id": 1,
+            },
+            num_times=1,
+        )
+
+        ctx = build_summary_data(
+            timestamp=self.now.timestamp(),
+            duration=ONE_DAY,
+            organization=self.organization,
+            daily=True,
+        )
+        top_projects_context_map = build_top_projects_map(ctx, self.user.id)
+        with self.tasks():
+            DailySummaryNotification(
+                organization=ctx.organization,
+                recipient=self.user,
+                provider=ExternalProviders.SLACK,
+                project_context=top_projects_context_map,
+            ).send()
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        assert (
+            '""" Traceback (most recent call last): File /\'/us...'
+            in blocks[4]["fields"][0]["text"]
+        )
+
     @responses.activate
     @with_feature("organizations:slack-block-kit")
     def test_limit_to_two_projects(self):