Repository: getsentry/sentry

Issue:
Internal Error when opening an issue that includes a deleted user in the activity
### Environment

SaaS (https://sentry.io/)

### Version

_No response_

### Link

_No response_

### DSN

_No response_

### Steps to Reproduce

Try to open an issue that includes a deleted user in the activity

### Expected Result

The issue can be viewed normally

### Actual Result

The screen shows a "There was an error loading data." error
![image](https://user-images.githubusercontent.com/81985895/228148425-95edc7a5-6915-485e-8974-a0d88d901f08.png)
On the network tab, a 500 fetch error can be seen with the response:
`{"detail":"Internal Error","errorId":"{error_ID}"}`
Searching for that ID in Sentry's Sentry leads to a KeyError with the user ID of a deleted user

More details in the internal ticket.
[Ticket on Zendesk](https://sentry.zendesk.com/agent/tickets/82420)

┆Issue is synchronized with this [Jira Improvement](https://getsentry.atlassian.net/browse/FEEDBACK-1797) by [Unito](https://www.unito.io)



Discussion:
Assigning to @getsentry/support for [routing](https://open.sentry.io/triage/#2-route), due by **<time datetime=2023-03-29T00:00:00.000Z>Tuesday, March 28th at 5:00 pm</time> (sfo)**. ⏲️
Routing to @getsentry/workflow for [triage](https://develop.sentry.dev/processing-tickets/#3-triage), due by **<time datetime=2023-03-30T00:00:00.000Z>Wednesday, March 29th at 5:00 pm</time> (sfo)**. ⏲️

Resolving patch:
diff --git a/src/sentry/api/serializers/models/activity.py b/src/sentry/api/serializers/models/activity.py
--- a/src/sentry/api/serializers/models/activity.py
+++ b/src/sentry/api/serializers/models/activity.py
@@ -77,7 +77,7 @@ def get_attrs(self, item_list, user):
 
         return {
             item: {
-                "user": users[str(item.user_id)] if item.user_id else None,
+                "user": users.get(str(item.user_id)) if item.user_id else None,
                 "source": groups.get(item.data["source_id"])
                 if item.type == ActivityType.UNMERGE_DESTINATION.value
                 else None,


Test patch:
diff --git a/tests/sentry/api/endpoints/test_group_details.py b/tests/sentry/api/endpoints/test_group_details.py
--- a/tests/sentry/api/endpoints/test_group_details.py
+++ b/tests/sentry/api/endpoints/test_group_details.py
@@ -229,6 +229,28 @@ def test_ratelimit(self):
             response = self.client.get(url, sort_by="date", limit=1)
             assert response.status_code == 429
 
+    def test_with_deleted_user_activity(self):
+        self.login_as(user=self.user)
+        user = self.create_user("foo@example.com")
+
+        group = self.create_group()
+        Activity.objects.create(
+            group=group,
+            project=self.project,
+            type=ActivityType.NOTE.value,
+            user_id=user.id,
+            data={"text": "This is bad"},
+            datetime=timezone.now(),
+        )
+
+        with exempt_from_silo_limits():
+            user.delete()
+
+        url = f"/api/0/issues/{group.id}/"
+        response = self.client.get(url, format="json")
+
+        assert response.status_code == 200, response.content
+
 
 @region_silo_test(stable=True)
 class GroupUpdateTest(APITestCase):