Browse Source

profiling: throw if txn param is undefined (#57042)

transaction is a required qs param.
Jonas 1 year ago
parent
commit
cc7c2fa8cc

+ 18 - 6
static/app/views/profiling/profileSummary/index.tsx

@@ -6,6 +6,7 @@ import type {Location} from 'history';
 import {LinkButton} from 'sentry/components/button';
 import DatePageFilter from 'sentry/components/datePageFilter';
 import EnvironmentPageFilter from 'sentry/components/environmentPageFilter';
+import ErrorBoundary from 'sentry/components/errorBoundary';
 import SearchBar from 'sentry/components/events/searchBar';
 import IdBadge from 'sentry/components/idBadge';
 import * as Layout from 'sentry/components/layouts/thirds';
@@ -48,7 +49,7 @@ interface ProfileSummaryHeaderProps {
   organization: Organization;
   project: Project | null;
   query: string;
-  transaction: string | undefined;
+  transaction: string;
 }
 function ProfileSummaryHeader(props: ProfileSummaryHeaderProps) {
   const breadcrumbTrails: ProfilingBreadcrumbsProps['trails'] = useMemo(() => {
@@ -64,7 +65,7 @@ function ProfileSummaryHeader(props: ProfileSummaryHeaderProps) {
         payload: {
           projectSlug: props.project?.slug ?? '',
           query: props.location.query,
-          transaction: props.transaction ?? '',
+          transaction: props.transaction,
         },
       },
     ];
@@ -207,6 +208,15 @@ function ProfileSummaryPage(props: ProfileSummaryPageProps) {
   );
 
   const transaction = decodeScalar(props.location.query.transaction);
+
+  if (!transaction) {
+    throw new TypeError(
+      `Profile summary requires a transaction query params, got ${
+        transaction?.toString() ?? transaction
+      }`
+    );
+  }
+
   const rawQuery = decodeScalar(props.location?.query?.query, '');
 
   const projectIds: number[] = useMemo(() => {
@@ -244,7 +254,7 @@ function ProfileSummaryPage(props: ProfileSummaryPageProps) {
     return search.formatString();
   }, [rawQuery, transaction]);
 
-  const {data} = useAggregateFlamegraphQuery({transaction: transaction ?? ''});
+  const {data} = useAggregateFlamegraphQuery({transaction});
 
   return (
     <SentryDocumentTitle
@@ -309,8 +319,8 @@ function ProfileSummaryPage(props: ProfileSummaryPageProps) {
               </ProfileGroupProvider>
             </ProfileVisualization>
             <ProfileDigest>
-              <MostRegressedProfileFunctions transaction={transaction ?? ''} />
-              <SlowestProfileFunctions transaction={transaction ?? ''} />
+              <MostRegressedProfileFunctions transaction={transaction} />
+              <SlowestProfileFunctions transaction={transaction} />
             </ProfileDigest>
           </ProfileVisualizationContainer>
         </PageFiltersContainer>
@@ -354,7 +364,9 @@ export default function ProfileSummaryPageToggle(props: ProfileSummaryPageProps)
   if (organization.features.includes('profiling-summary-redesign')) {
     return (
       <ProfileSummaryContainer data-test-id="profile-summary-redesign">
-        <ProfileSummaryPage {...props} />
+        <ErrorBoundary>
+          <ProfileSummaryPage {...props} />
+        </ErrorBoundary>
       </ProfileSummaryContainer>
     );
   }

+ 40 - 4
static/app/views/profiling/profileSummary/profileSummaryPage.spec.tsx

@@ -1,3 +1,6 @@
+import {Location} from 'history';
+import {GlobalSelection} from 'sentry-fixture/globalSelection';
+
 import {render, screen} from 'sentry-test/reactTestingLibrary';
 
 import OrganizationStore from 'sentry/stores/organizationStore';
@@ -54,11 +57,35 @@ describe('ProfileSummaryPage', () => {
       body: [],
     });
 
+    MockApiClient.addMockResponse({
+      url: `/organizations/${organization.slug}/events-stats/`,
+      body: [],
+    });
+
+    MockApiClient.addMockResponse({
+      url: `/organizations/${organization.slug}/profiling/flamegraph/`,
+      body: [],
+    });
+
+    MockApiClient.addMockResponse({
+      url: `/organizations/${organization.slug}/events/`,
+      body: [],
+    });
+
+    MockApiClient.addMockResponse({
+      url: `/organizations/${organization.slug}/profiling/function-trends/`,
+      body: [],
+    });
+
     render(
       <ProfileSummaryPage
         params={{}}
-        selection={TestStubs.GlobalSelection()}
-        location={TestStubs.location()}
+        selection={GlobalSelection()}
+        location={
+          {
+            query: {transaction: 'fancyservice'},
+          } as unknown as Location
+        }
       />,
       {
         organization,
@@ -76,6 +103,11 @@ describe('ProfileSummaryPage', () => {
     });
     OrganizationStore.onUpdate(organization);
 
+    MockApiClient.addMockResponse({
+      url: `/organizations/${organization.slug}/projects/`,
+      body: [TestStubs.Project()],
+    });
+
     MockApiClient.addMockResponse({
       url: `/organizations/${organization.slug}/profiling/filters/`,
       body: [],
@@ -104,8 +136,12 @@ describe('ProfileSummaryPage', () => {
     render(
       <ProfileSummaryPage
         params={{}}
-        selection={TestStubs.GlobalSelection()}
-        location={TestStubs.location()}
+        selection={GlobalSelection()}
+        location={
+          {
+            query: {transaction: 'fancyservice'},
+          } as unknown as Location
+        }
       />,
       {
         organization: TestStubs.Organization({