Browse Source

feat(issues): Add current event to the trace timeline (#64958)

Scott Cooper 1 year ago
parent
commit
72f77cec6a

+ 0 - 2
static/app/views/issueDetails/traceTimeline/traceLink.spec.tsx

@@ -29,7 +29,6 @@ describe('TraceLink', () => {
         'project.name': project.name,
         title: 'Slow DB Query',
         id: 'abc',
-        issue: 'SENTRY-ABC1',
         transaction: '/api/slow/',
       },
     ],
@@ -44,7 +43,6 @@ describe('TraceLink', () => {
         'project.name': project.name,
         title: 'AttributeError: Something Failed',
         id: event.id,
-        issue: 'SENTRY-2EYS',
         transaction: 'important.task',
         'event.type': 'error',
       },

+ 3 - 1
static/app/views/issueDetails/traceTimeline/traceLink.tsx

@@ -48,7 +48,9 @@ export function TraceLink({event}: TraceLinkProps) {
     >
       <span>
         {t('View Full Trace')}
-        {data.length > 0 && tn(' (%s issue)', ' (%s issues)', data.length)}
+        {data.length >= 100
+          ? t(' (100+ issues)')
+          : tn(' (%s issue)', ' (%s issues)', data.length)}
       </span>
       <IconChevron direction="right" size="xs" />
     </StyledLink>

+ 21 - 18
static/app/views/issueDetails/traceTimeline/traceTimeline.spec.tsx

@@ -15,6 +15,7 @@ jest.mock('sentry/utils/routeAnalytics/useRouteAnalyticsParams');
 describe('TraceTimeline', () => {
   const organization = OrganizationFixture({features: ['issues-trace-timeline']});
   const event = EventFixture({
+    dateCreated: '2024-01-24T09:09:03+00:00',
     contexts: {
       trace: {
         trace_id: '123',
@@ -23,6 +24,7 @@ describe('TraceTimeline', () => {
   });
   const project = ProjectFixture();
 
+  const emptyBody: TraceEventResponse = {data: [], meta: {fields: {}, units: {}}};
   const issuePlatformBody: TraceEventResponse = {
     data: [
       {
@@ -32,7 +34,6 @@ describe('TraceTimeline', () => {
         'project.name': project.name,
         title: 'Slow DB Query',
         id: 'abc',
-        issue: 'SENTRY-ABC1',
         transaction: '/api/slow/',
       },
     ],
@@ -47,7 +48,6 @@ describe('TraceTimeline', () => {
         'project.name': project.name,
         title: 'AttributeError: Something Failed',
         id: event.id,
-        issue: 'SENTRY-2EYS',
         transaction: 'important.task',
         'event.type': 'error',
         'stack.function': ['important.task', 'task.run'],
@@ -85,10 +85,7 @@ describe('TraceTimeline', () => {
   it('displays nothing if the only event is the current event', async () => {
     MockApiClient.addMockResponse({
       url: `/organizations/${organization.slug}/events/`,
-      body: {
-        data: [],
-        meta: {fields: {}, units: {}},
-      },
+      body: emptyBody,
       match: [MockApiClient.matchQuery({dataset: 'issuePlatform'})],
     });
     MockApiClient.addMockResponse({
@@ -106,18 +103,12 @@ describe('TraceTimeline', () => {
   it('displays nothing if there are no events', async () => {
     MockApiClient.addMockResponse({
       url: `/organizations/${organization.slug}/events/`,
-      body: {
-        data: [],
-        meta: {fields: {}, units: {}},
-      },
+      body: emptyBody,
       match: [MockApiClient.matchQuery({dataset: 'issuePlatform'})],
     });
     MockApiClient.addMockResponse({
       url: `/organizations/${organization.slug}/events/`,
-      body: {
-        data: [],
-        meta: {fields: {}, units: {}},
-      },
+      body: emptyBody,
       match: [MockApiClient.matchQuery({dataset: 'discover'})],
     });
     render(<TraceTimeline event={event} />, {organization});
@@ -135,14 +126,26 @@ describe('TraceTimeline', () => {
     });
     MockApiClient.addMockResponse({
       url: `/organizations/${organization.slug}/events/`,
-      body: {
-        data: [],
-        meta: {fields: {}, units: {}},
-      },
+      body: emptyBody,
       match: [MockApiClient.matchQuery({dataset: 'discover'})],
     });
     render(<TraceTimeline event={event} />, {organization});
     // Checking for the presence of seconds
     expect(await screen.findAllByText(/\d{1,2}:\d{2}:\d{2} (AM|PM)/)).toHaveLength(5);
   });
+
+  it('adds the current event if not in the api response', async () => {
+    MockApiClient.addMockResponse({
+      url: `/organizations/${organization.slug}/events/`,
+      body: issuePlatformBody,
+      match: [MockApiClient.matchQuery({dataset: 'issuePlatform'})],
+    });
+    MockApiClient.addMockResponse({
+      url: `/organizations/${organization.slug}/events/`,
+      body: emptyBody,
+      match: [MockApiClient.matchQuery({dataset: 'discover'})],
+    });
+    render(<TraceTimeline event={event} />, {organization});
+    expect(await screen.findByLabelText('Current Event')).toBeInTheDocument();
+  });
 });

+ 18 - 3
static/app/views/issueDetails/traceTimeline/useTraceTimelineEvents.tsx

@@ -8,7 +8,6 @@ import useOrganization from 'sentry/utils/useOrganization';
 
 interface BaseEvent {
   id: string;
-  issue: string;
   'issue.id': number;
   project: string;
   'project.name': string;
@@ -54,7 +53,7 @@ export function useTraceTimelineEvents(
         query: {
           // Get performance issues
           dataset: DiscoverDatasets.ISSUE_PLATFORM,
-          field: ['title', 'project', 'timestamp', 'issue.id', 'issue', 'transaction'],
+          field: ['title', 'project', 'timestamp', 'issue.id', 'transaction'],
           per_page: 100,
           query: `trace:${traceId}`,
           referrer: 'api.issues.issue_events',
@@ -85,7 +84,6 @@ export function useTraceTimelineEvents(
             'project',
             'timestamp',
             'issue.id',
-            'issue',
             'transaction',
             'event.type',
             'stack.function',
@@ -116,7 +114,23 @@ export function useTraceTimelineEvents(
       };
     }
 
+    // Events is unsorted since they're grouped by date later
     const events = [...issuePlatformData.data, ...discoverData.data];
+
+    // The current event might be missing when there is a large number of issues
+    const hasCurrentEvent = events.some(e => e.id === event.id);
+    if (!hasCurrentEvent) {
+      events.push({
+        id: event.id,
+        'issue.id': Number(event.groupID),
+        project: event.projectID,
+        // The project name for current event is not used
+        'project.name': '',
+        timestamp: event.dateCreated!,
+        title: event.title,
+        transaction: '',
+      });
+    }
     const timestamps = events.map(e => new Date(e.timestamp).getTime());
     const startTimestamp = Math.min(...timestamps);
     const endTimestamp = Math.max(...timestamps);
@@ -126,6 +140,7 @@ export function useTraceTimelineEvents(
       endTimestamp,
     };
   }, [
+    event,
     issuePlatformData,
     discoverData,
     isLoadingIssuePlatform,