Skip to content

Conversation

@malwilley
Copy link
Member

The issue details page for metric issues was still using the old charts which used the old incidents model. Issues made with new detectors would not have that data. Plus, we have updated charts that we want to use on this page.

While doing this, I refactored the metric alert chart to export useMetricDetectorChart() which makes the data fetching queries and returns the chart props. That way issue details and the detector page can reuse that logic while still rendering the loading/error states differently.

Before (chart did not load because incidents model does not exist):

CleanShot 2025-11-07 at 14 39 44@2x

After:

CleanShot 2025-11-07 at 14 39 06@2x

@malwilley malwilley requested review from a team as code owners November 7, 2025 22:43
@github-actions github-actions bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Nov 7, 2025
@malwilley malwilley removed the request for review from a team November 7, 2025 22:43
Comment on lines 50 to 54
if (isDetectorLoading) {
return <MetricIssueChartPlaceholder />;
}

return (
<MetricChartSection>
<MetricIssueChartContent
rule={rule}
timePeriod={timePeriod}
project={project}
incidents={incidents}
/>
</MetricChartSection>
);
return <MetricIssueChartContent detector={detector} openPeriods={openPeriods} />;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Accessing detector.dataSources without a null check can cause a TypeError when useDetectorQuery is disabled.
Severity: CRITICAL | Confidence: 1.00

🔍 Detailed Analysis

The useDetectorQuery hook is configured with a conditional enabled flag. If detectorId is falsy or detectorDetails?.detectorType is not 'metric_alert', the query will not execute, resulting in detector being undefined. The MetricIssueChartContent component then attempts to access properties like detector.dataSources[0].queryObj.snubaQuery without a preceding null check, which triggers a TypeError and causes the application to crash.

💡 Suggested Fix

Add a null check for the detector variable before rendering MetricIssueChartContent. If detector is undefined, render a placeholder component instead.

🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: static/app/views/issueDetails/metricIssues/metricIssueChart.tsx#L50-L54

Potential issue: The `useDetectorQuery` hook is configured with a conditional `enabled`
flag. If `detectorId` is falsy or `detectorDetails?.detectorType` is not
`'metric_alert'`, the query will not execute, resulting in `detector` being `undefined`.
The `MetricIssueChartContent` component then attempts to access properties like
`detector.dataSources[0].queryObj.snubaQuery` without a preceding null check, which
triggers a `TypeError` and causes the application to crash.

Did we get this right? 👍 / 👎 to inform future reviews.

@codecov
Copy link

codecov bot commented Nov 7, 2025

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
12377 1 12376 10
View the top 1 failed test(s) by shortest run time
DetectorSection displays the detector details for a metric issue
Stack Traces | 0.026s run time
TestingLibraryElementError: Unable to find an element with the text: Metric Monitor. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
...
    at Object.getElementError (.../sentry/node_modules/.pnpm/@testing-library+dom@10.4.0/node_modules/@.../dom/dist/config.js:37:19)
    at .../sentry/node_modules/.pnpm/@testing-library+dom@10.4.0/node_modules/@.../dom/dist/query-helpers.js:76:38
    at .../sentry/node_modules/.pnpm/@testing-library+dom@10.4.0/node_modules/@.../dom/dist/query-helpers.js:52:17
    at .../sentry/node_modules/.pnpm/@testing-library+dom@10.4.0/node_modules/@.../dom/dist/query-helpers.js:95:19
    at Object.getByText (.../streamline/sidebar/detectorSection.spec.tsx:61:19)
    at Promise.finally.completed (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:1559:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:1499:10)
    at _callCircusTest (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:1009:40)
    at processTicksAndRejections (node:internal/process/task_queues:105:5)
    at _runTest (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:949:3)
    at _runTestsForDescribeBlock (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:839:13)
    at _runTestsForDescribeBlock (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:829:11)
    at run (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:757:3)
    at runAndTransformResultsToJestFormat (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/jestAdapterInit.js:1920:21)
    at jestAdapter (.../sentry/node_modules/.pnpm/jest-circus@30.0.4_babel-plugin-macros@3.1..../jest-circus/build/runner.js:101:19)
    at runTestInternal (.../sentry/node_modules/.pnpm/jest-runner@30.0..../jest-runner/build/testWorker.js:272:16)
    at runTest (.../sentry/node_modules/.pnpm/jest-runner@30.0..../jest-runner/build/testWorker.js:340:7)
    at Object.worker (.../sentry/node_modules/.pnpm/jest-runner@30.0..../jest-runner/build/testWorker.js:494:12)

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@malwilley malwilley requested a review from a team as a code owner November 7, 2025 23:32
/>
</MetricChartSection>
);
return <MetricIssueChartContent detector={detector} openPeriods={openPeriods} />;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Safeguard against missing detector data crashes.

The detector might be undefined when passed to MetricIssueChartContent because the query can be disabled (enabled: false when detectorId is missing or detectorType is incorrect), causing the component to crash when attempting to access detector.dataSources[0] in useMetricDetectorChart. The code only checks isDetectorError and isDetectorPending but doesn't validate that detector is defined before rendering.

Fix in Cursor Fix in Web

@malwilley malwilley merged commit 7884775 into master Nov 10, 2025
47 checks passed
@malwilley malwilley deleted the malwilley/feat/use-new-metric-detector-charts-in-issue-details branch November 10, 2025 21:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants