From b6ce85dad84219e921166996c09af73605d2dc00 Mon Sep 17 00:00:00 2001
From: Abdullah Khan
Date: Fri, 5 Dec 2025 16:31:39 -0500
Subject: [PATCH 1/2] feat(trace-tree-node): Mitigating SpanNode type guard
usage
---
.../details/missingInstrumentation.tsx | 144 ++++--------------
.../details/span/sections/keys.tsx | 12 +-
.../newTraceDetails/traceModels/traceTree.tsx | 4 +-
.../traceModels/traceTreeNode/baseNode.tsx | 7 +
.../traceModels/traceTreeNode/eapSpanNode.tsx | 4 +-
.../traceTreeNode/uptimeCheckNode.tsx | 4 +-
.../traceTreeNode/uptimeCheckTimingNode.tsx | 4 +-
.../traceRow/traceEAPSpanRow.tsx | 115 ++++++++++++++
.../newTraceDetails/traceRow/traceSpanRow.tsx | 40 +----
.../traceRow/traceUptimeCheckNode.tsx | 105 +++++++++++++
.../traceRow/traceUptimeCheckTimingNode.tsx | 105 +++++++++++++
11 files changed, 383 insertions(+), 161 deletions(-)
create mode 100644 static/app/views/performance/newTraceDetails/traceRow/traceEAPSpanRow.tsx
create mode 100644 static/app/views/performance/newTraceDetails/traceRow/traceUptimeCheckNode.tsx
create mode 100644 static/app/views/performance/newTraceDetails/traceRow/traceUptimeCheckTimingNode.tsx
diff --git a/static/app/views/performance/newTraceDetails/traceDrawer/details/missingInstrumentation.tsx b/static/app/views/performance/newTraceDetails/traceDrawer/details/missingInstrumentation.tsx
index d6c4ad7bd3a3c8..14a6cfaed8cfe9 100644
--- a/static/app/views/performance/newTraceDetails/traceDrawer/details/missingInstrumentation.tsx
+++ b/static/app/views/performance/newTraceDetails/traceDrawer/details/missingInstrumentation.tsx
@@ -1,21 +1,12 @@
import {useMemo} from 'react';
import {ExternalLink} from 'sentry/components/core/link';
-import LoadingError from 'sentry/components/loadingError';
-import LoadingIndicator from 'sentry/components/loadingIndicator';
import {t, tct} from 'sentry/locale';
-import type {EventTransaction} from 'sentry/types/event';
-import type {Project} from 'sentry/types/project';
import useProjects from 'sentry/utils/useProjects';
import {useTransaction} from 'sentry/views/performance/newTraceDetails/traceApi/useTransaction';
import {getCustomInstrumentationLink} from 'sentry/views/performance/newTraceDetails/traceConfigurations';
import {ProfilePreview} from 'sentry/views/performance/newTraceDetails/traceDrawer/details/profiling/profilePreview';
import type {TraceTreeNodeDetailsProps} from 'sentry/views/performance/newTraceDetails/traceDrawer/tabs/traceTreeNodeDetails';
-import {
- isEAPSpanNode,
- isSpanNode,
-} from 'sentry/views/performance/newTraceDetails/traceGuards';
-import type {EapSpanNode} from 'sentry/views/performance/newTraceDetails/traceModels/traceTreeNode/eapSpanNode';
import type {NoInstrumentationNode} from 'sentry/views/performance/newTraceDetails/traceModels/traceTreeNode/noInstrumentationNode';
import {ProfileGroupProvider} from 'sentry/views/profiling/profileGroupProvider';
import {ProfileContext, ProfilesProvider} from 'sentry/views/profiling/profilesProvider';
@@ -23,62 +14,17 @@ import {ProfileContext, ProfilesProvider} from 'sentry/views/profiling/profilesP
import {TraceDrawerComponents} from './styles';
import {getProfileMeta} from './utils';
-interface BaseProps extends TraceTreeNodeDetailsProps {
- event: EventTransaction | null;
- profileId: string | undefined;
- profileMeta: ReturnType;
- profilerId: string | undefined;
- project: Project | undefined;
-}
-
export function MissingInstrumentationNodeDetails({
...props
}: TraceTreeNodeDetailsProps) {
const {node} = props;
const {projects} = useProjects();
+ const previous = node.previous;
- if (isEAPSpanNode(node.previous)) {
- return ;
- }
-
- if (isSpanNode(node.previous)) {
- const event = node.previous.event;
- const project = projects.find(proj => proj.slug === event?.projectSlug);
- const profileMeta = getProfileMeta(event) || '';
- const profileContext = event?.contexts?.profile ?? {};
-
- return (
-
- );
- }
-
- return null;
-}
-
-function EAPMissingInstrumentationNodeDetails({
- projects,
- ...props
-}: TraceTreeNodeDetailsProps & {
- projects: Project[];
-}) {
- const {node} = props;
- const previous = node.previous as EapSpanNode;
-
- const {
- data: eventTransaction = null,
- isLoading: isEventTransactionLoading,
- isError: isEventTransactionError,
- } = useTransaction({
- event_id: previous.value.transaction_id,
+ const {data: eventTransaction = null} = useTransaction({
+ event_id: previous.transactionId ?? '',
organization: props.organization,
- project_slug: previous.value.project_slug,
+ project_slug: previous.projectSlug ?? '',
});
const profileMeta = useMemo(
@@ -86,39 +32,9 @@ function EAPMissingInstrumentationNodeDetails({
[eventTransaction]
);
- if (isEventTransactionLoading) {
- return ;
- }
-
- if (isEventTransactionError) {
- return ;
- }
-
const project = projects.find(proj => proj.slug === eventTransaction?.projectSlug);
const profileContext = eventTransaction?.contexts?.profile ?? {};
- return (
-
- );
-}
-
-function BaseMissingInstrumentationNodeDetails({
- node,
- organization,
- onTabScrollToNode,
- profileMeta,
- project,
- event,
- profileId,
- profilerId,
-}: BaseProps) {
return (
@@ -135,8 +51,8 @@ function BaseMissingInstrumentationNodeDetails({
@@ -150,29 +66,31 @@ function BaseMissingInstrumentationNodeDetails({
}
)}
-
-
- {profiles => (
-
-
-
- )}
-
-
+ {eventTransaction ? (
+
+
+ {profiles => (
+
+
+
+ )}
+
+
+ ) : null}
{t("If you'd prefer, you can also turn the feature off in the settings above.")}
diff --git a/static/app/views/performance/newTraceDetails/traceDrawer/details/span/sections/keys.tsx b/static/app/views/performance/newTraceDetails/traceDrawer/details/span/sections/keys.tsx
index 1d675587a4bae3..692c27bd29ef1e 100644
--- a/static/app/views/performance/newTraceDetails/traceDrawer/details/span/sections/keys.tsx
+++ b/static/app/views/performance/newTraceDetails/traceDrawer/details/span/sections/keys.tsx
@@ -23,7 +23,6 @@ import {
type SectionCardKeyValueList,
} from 'sentry/views/performance/newTraceDetails/traceDrawer/details/styles';
import {TraceDrawerActionValueKind} from 'sentry/views/performance/newTraceDetails/traceDrawer/details/utils';
-import {isSpanNode} from 'sentry/views/performance/newTraceDetails/traceGuards';
import type {SpanNode} from 'sentry/views/performance/newTraceDetails/traceModels/traceTreeNode/spanNode';
import {getPerformanceDuration} from 'sentry/views/performance/utils/getPerformanceDuration';
@@ -77,11 +76,12 @@ function getSpanAggregateMeasurements(node: SpanNode) {
let sum = 0;
node.forEachChild(n => {
- if (
- isSpanNode(n) &&
- typeof n?.value?.measurements?.ai_total_tokens_used?.value === 'number'
- ) {
- sum += n.value.measurements.ai_total_tokens_used.value;
+ const tokens =
+ typeof n.measurements?.ai_total_tokens_used === 'number'
+ ? n.measurements?.ai_total_tokens_used
+ : (n.measurements?.ai_total_tokens_used?.value ?? 0);
+ if (tokens) {
+ sum += tokens;
}
});
return [
diff --git a/static/app/views/performance/newTraceDetails/traceModels/traceTree.tsx b/static/app/views/performance/newTraceDetails/traceModels/traceTree.tsx
index 9c0d0ee3f5bd4a..5e8c3bf77d53d4 100644
--- a/static/app/views/performance/newTraceDetails/traceModels/traceTree.tsx
+++ b/static/app/views/performance/newTraceDetails/traceModels/traceTree.tsx
@@ -523,7 +523,7 @@ export class TraceTree extends TraceTreeEventDispatcher {
tree,
c,
c.space[0],
- c.value.measurements,
+ c.measurements,
tree.vitals,
tree.vital_types
)
@@ -678,7 +678,7 @@ export class TraceTree extends TraceTreeEventDispatcher {
tree,
node,
baseTraceNode.space[0],
- node.value.measurements,
+ node.measurements,
this.vitals,
this.vital_types
)
diff --git a/static/app/views/performance/newTraceDetails/traceModels/traceTreeNode/baseNode.tsx b/static/app/views/performance/newTraceDetails/traceModels/traceTreeNode/baseNode.tsx
index 02c085f6038e18..93cbe40e4b1b5d 100644
--- a/static/app/views/performance/newTraceDetails/traceModels/traceTreeNode/baseNode.tsx
+++ b/static/app/views/performance/newTraceDetails/traceModels/traceTreeNode/baseNode.tsx
@@ -2,6 +2,7 @@ import type {Theme} from '@emotion/react';
import type {Client} from 'sentry/api';
import {pickBarColor} from 'sentry/components/performance/waterfall/utils';
+import type {Measurement} from 'sentry/types/event';
import type {Organization} from 'sentry/types/organization';
import type {TraceMetaQueryResults} from 'sentry/views/performance/newTraceDetails/traceApi/useTraceMeta';
import type {TraceTreeNodeDetailsProps} from 'sentry/views/performance/newTraceDetails/traceDrawer/tabs/traceTreeNodeDetails';
@@ -326,6 +327,12 @@ export abstract class BaseNode | Record | undefined {
+ return this.value && 'measurements' in this.value
+ ? this.value.measurements
+ : undefined;
+ }
+
get attributes(): Record | undefined {
return this.value && 'additional_attributes' in this.value
? this.value.additional_attributes
diff --git a/static/app/views/performance/newTraceDetails/traceModels/traceTreeNode/eapSpanNode.tsx b/static/app/views/performance/newTraceDetails/traceModels/traceTreeNode/eapSpanNode.tsx
index 5dc4ce0cf921cd..ff1629e3b2d18a 100644
--- a/static/app/views/performance/newTraceDetails/traceModels/traceTreeNode/eapSpanNode.tsx
+++ b/static/app/views/performance/newTraceDetails/traceModels/traceTreeNode/eapSpanNode.tsx
@@ -11,8 +11,8 @@ import {
isEAPTransaction,
} from 'sentry/views/performance/newTraceDetails/traceGuards';
import type {TraceTree} from 'sentry/views/performance/newTraceDetails/traceModels/traceTree';
+import {TraceEAPSpanRow} from 'sentry/views/performance/newTraceDetails/traceRow/traceEAPSpanRow';
import type {TraceRowProps} from 'sentry/views/performance/newTraceDetails/traceRow/traceRow';
-import {TraceSpanRow} from 'sentry/views/performance/newTraceDetails/traceRow/traceSpanRow';
import {BaseNode, type TraceTreeNodeExtra} from './baseNode';
import {traceChronologicalSort} from './utils';
@@ -282,7 +282,7 @@ export class EapSpanNode extends BaseNode {
renderWaterfallRow(
props: TraceRowProps
): React.ReactNode {
- return ;
+ return ;
}
renderDetails(
diff --git a/static/app/views/performance/newTraceDetails/traceModels/traceTreeNode/uptimeCheckNode.tsx b/static/app/views/performance/newTraceDetails/traceModels/traceTreeNode/uptimeCheckNode.tsx
index d1d676fe8b6883..9d6904640ac45b 100644
--- a/static/app/views/performance/newTraceDetails/traceModels/traceTreeNode/uptimeCheckNode.tsx
+++ b/static/app/views/performance/newTraceDetails/traceModels/traceTreeNode/uptimeCheckNode.tsx
@@ -7,7 +7,7 @@ import {UptimeNodeDetails} from 'sentry/views/performance/newTraceDetails/traceD
import type {TraceTreeNodeDetailsProps} from 'sentry/views/performance/newTraceDetails/traceDrawer/tabs/traceTreeNodeDetails';
import type {TraceTree} from 'sentry/views/performance/newTraceDetails/traceModels/traceTree';
import type {TraceRowProps} from 'sentry/views/performance/newTraceDetails/traceRow/traceRow';
-import {TraceSpanRow} from 'sentry/views/performance/newTraceDetails/traceRow/traceSpanRow';
+import {TraceUptimeCheckNodeRow} from 'sentry/views/performance/newTraceDetails/traceRow/traceUptimeCheckNode';
import {BaseNode, type TraceTreeNodeExtra} from './baseNode';
import {UptimeCheckTimingNode} from './uptimeCheckTimingNode';
@@ -140,7 +140,7 @@ export class UptimeCheckNode extends BaseNode {
renderWaterfallRow(
props: TraceRowProps
): React.ReactNode {
- return ;
+ return ;
}
renderDetails(
diff --git a/static/app/views/performance/newTraceDetails/traceModels/traceTreeNode/uptimeCheckTimingNode.tsx b/static/app/views/performance/newTraceDetails/traceModels/traceTreeNode/uptimeCheckTimingNode.tsx
index e4acda5f6c6e18..cf819b572a3b60 100644
--- a/static/app/views/performance/newTraceDetails/traceModels/traceTreeNode/uptimeCheckTimingNode.tsx
+++ b/static/app/views/performance/newTraceDetails/traceModels/traceTreeNode/uptimeCheckTimingNode.tsx
@@ -5,7 +5,7 @@ import {UptimeTimingDetails} from 'sentry/views/performance/newTraceDetails/trac
import type {TraceTreeNodeDetailsProps} from 'sentry/views/performance/newTraceDetails/traceDrawer/tabs/traceTreeNodeDetails';
import type {TraceTree} from 'sentry/views/performance/newTraceDetails/traceModels/traceTree';
import type {TraceRowProps} from 'sentry/views/performance/newTraceDetails/traceRow/traceRow';
-import {TraceSpanRow} from 'sentry/views/performance/newTraceDetails/traceRow/traceSpanRow';
+import {TraceUptimeCheckTimingNodeRow} from 'sentry/views/performance/newTraceDetails/traceRow/traceUptimeCheckTimingNode';
import {BaseNode} from './baseNode';
@@ -33,7 +33,7 @@ export class UptimeCheckTimingNode extends BaseNode
props: TraceRowProps
): React.ReactNode {
return (
- ) {
+ const spanId = props.node.id;
+
+ const childrenCount = getChildrenCount(props.node);
+
+ const icon = (
+
+ );
+
+ return (
+
+ props.tabIndex === 0
+ ? maybeFocusTraceRow(r, props.node, props.previouslyFocusedNodeRef)
+ : undefined
+ }
+ tabIndex={props.tabIndex}
+ className={`TraceRow ${props.rowSearchClassName} ${props.node.hasErrors ? props.node.maxIssueSeverity : ''}`}
+ onPointerDown={props.onRowClick}
+ onKeyDown={props.onRowKeyDown}
+ style={props.style}
+ >
+
+
+
+
+ {props.node.children.length > 0 || props.node.canFetchChildren ? (
+
+ )
+ }
+ status={props.node.fetchStatus}
+ expanded={props.node.expanded || props.node.hasFetchedChildren}
+ onDoubleClick={props.onExpandDoubleClick}
+ onClick={e =>
+ props.node.canFetchChildren ? props.onZoomIn(e) : props.onExpand(e)
+ }
+ >
+ {childrenCount > 0 ? TRACE_COUNT_FORMATTER.format(childrenCount) : null}
+
+ ) : null}
+
+ {icon}
+
+ {props.node.value.op && props.node.value.op !== 'default' && (
+
+ {props.node.value.op}
+ —
+
+ )}
+
+ {props.node.description
+ ? ellipsize(props.node.description, 100)
+ : (spanId ?? 'unknown')}
+
+
+
+
+
+
+
+
+
+ );
+}
+
+function getChildrenCount(node: EapSpanNode) {
+ if (node.value.is_transaction && !node.expanded) {
+ return node.children.length - node.directVisibleChildren.length;
+ }
+
+ return node.children.length;
+}
diff --git a/static/app/views/performance/newTraceDetails/traceRow/traceSpanRow.tsx b/static/app/views/performance/newTraceDetails/traceRow/traceSpanRow.tsx
index 5cfda05c21b425..9ad0a507229505 100644
--- a/static/app/views/performance/newTraceDetails/traceRow/traceSpanRow.tsx
+++ b/static/app/views/performance/newTraceDetails/traceRow/traceSpanRow.tsx
@@ -1,19 +1,9 @@
import React from 'react';
import {PlatformIcon} from 'platformicons';
-import {IconSentry, IconTimer} from 'sentry/icons';
import {ellipsize} from 'sentry/utils/string/ellipsize';
-import {
- isEAPTransactionNode,
- isSpanNode,
- isUptimeCheckNode,
- isUptimeCheckTimingNode,
-} from 'sentry/views/performance/newTraceDetails/traceGuards';
import {TraceIcons} from 'sentry/views/performance/newTraceDetails/traceIcons';
-import type {EapSpanNode} from 'sentry/views/performance/newTraceDetails/traceModels/traceTreeNode/eapSpanNode';
import type {SpanNode} from 'sentry/views/performance/newTraceDetails/traceModels/traceTreeNode/spanNode';
-import type {UptimeCheckNode} from 'sentry/views/performance/newTraceDetails/traceModels/traceTreeNode/uptimeCheckNode';
-import type {UptimeCheckTimingNode} from 'sentry/views/performance/newTraceDetails/traceModels/traceTreeNode/uptimeCheckTimingNode';
import {TraceBar} from 'sentry/views/performance/newTraceDetails/traceRow/traceBar';
import {
maybeFocusTraceRow,
@@ -23,25 +13,15 @@ import {
type TraceRowProps,
} from 'sentry/views/performance/newTraceDetails/traceRow/traceRow';
-export function TraceSpanRow(
- props: TraceRowProps
-) {
+export function TraceSpanRow(props: TraceRowProps) {
const spanId = props.node.id;
- const childrenCount = getChildrenCount(props.node);
-
- const icon = isUptimeCheckNode(props.node) ? (
-
- ) : isUptimeCheckTimingNode(props.node) ? (
-
- ) : (
+ const icon = (
);
const isPrefetch =
- isSpanNode(props.node) &&
- props.node.value.data &&
- !!props.node.value.data['http.request.prefetch'];
+ props.node.value.data && !!props.node.value.data['http.request.prefetch'];
return (
- {childrenCount > 0 ? TRACE_COUNT_FORMATTER.format(childrenCount) : null}
+ {props.node.children.length > 0
+ ? TRACE_COUNT_FORMATTER.format(props.node.children.length)
+ : null}
) : null}
@@ -127,13 +109,3 @@ export function TraceSpanRow(
);
}
-
-function getChildrenCount(
- node: SpanNode | EapSpanNode | UptimeCheckNode | UptimeCheckTimingNode
-) {
- if (isEAPTransactionNode(node) && !node.expanded) {
- return node.children.length - node.directVisibleChildren.length;
- }
-
- return node.children.length;
-}
diff --git a/static/app/views/performance/newTraceDetails/traceRow/traceUptimeCheckNode.tsx b/static/app/views/performance/newTraceDetails/traceRow/traceUptimeCheckNode.tsx
new file mode 100644
index 00000000000000..1346dbb89e4dad
--- /dev/null
+++ b/static/app/views/performance/newTraceDetails/traceRow/traceUptimeCheckNode.tsx
@@ -0,0 +1,105 @@
+import React from 'react';
+
+import {IconSentry} from 'sentry/icons';
+import {ellipsize} from 'sentry/utils/string/ellipsize';
+import {TraceIcons} from 'sentry/views/performance/newTraceDetails/traceIcons';
+import type {UptimeCheckNode} from 'sentry/views/performance/newTraceDetails/traceModels/traceTreeNode/uptimeCheckNode';
+import {TraceBar} from 'sentry/views/performance/newTraceDetails/traceRow/traceBar';
+import {
+ maybeFocusTraceRow,
+ TRACE_COUNT_FORMATTER,
+ TraceChildrenButton,
+ TraceRowConnectors,
+ type TraceRowProps,
+} from 'sentry/views/performance/newTraceDetails/traceRow/traceRow';
+
+export function TraceUptimeCheckNodeRow(props: TraceRowProps) {
+ const spanId = props.node.id;
+
+ const icon = ;
+
+ return (
+
+ props.tabIndex === 0
+ ? maybeFocusTraceRow(r, props.node, props.previouslyFocusedNodeRef)
+ : undefined
+ }
+ tabIndex={props.tabIndex}
+ className={`TraceRow ${props.rowSearchClassName} ${props.node.hasErrors ? props.node.maxIssueSeverity : ''}`}
+ onPointerDown={props.onRowClick}
+ onKeyDown={props.onRowKeyDown}
+ style={props.style}
+ >
+
+
+
+
+ {props.node.children.length > 0 || props.node.canFetchChildren ? (
+
+ )
+ }
+ status={props.node.fetchStatus}
+ expanded={props.node.expanded || props.node.hasFetchedChildren}
+ onDoubleClick={props.onExpandDoubleClick}
+ onClick={e =>
+ props.node.canFetchChildren ? props.onZoomIn(e) : props.onExpand(e)
+ }
+ >
+ {props.node.children.length > 0
+ ? TRACE_COUNT_FORMATTER.format(props.node.children.length)
+ : null}
+
+ ) : null}
+
+ {icon}
+
+ {props.node.value.op && props.node.value.op !== 'default' && (
+
+ {props.node.value.op}
+ —
+
+ )}
+
+ {props.node.description
+ ? ellipsize(props.node.description, 100)
+ : (spanId ?? 'unknown')}
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/static/app/views/performance/newTraceDetails/traceRow/traceUptimeCheckTimingNode.tsx b/static/app/views/performance/newTraceDetails/traceRow/traceUptimeCheckTimingNode.tsx
new file mode 100644
index 00000000000000..569eead20447c3
--- /dev/null
+++ b/static/app/views/performance/newTraceDetails/traceRow/traceUptimeCheckTimingNode.tsx
@@ -0,0 +1,105 @@
+import React from 'react';
+
+import {IconTimer} from 'sentry/icons';
+import {ellipsize} from 'sentry/utils/string/ellipsize';
+import {TraceIcons} from 'sentry/views/performance/newTraceDetails/traceIcons';
+import type {UptimeCheckTimingNode} from 'sentry/views/performance/newTraceDetails/traceModels/traceTreeNode/uptimeCheckTimingNode';
+import {TraceBar} from 'sentry/views/performance/newTraceDetails/traceRow/traceBar';
+import {
+ maybeFocusTraceRow,
+ TRACE_COUNT_FORMATTER,
+ TraceChildrenButton,
+ TraceRowConnectors,
+ type TraceRowProps,
+} from 'sentry/views/performance/newTraceDetails/traceRow/traceRow';
+
+export function TraceUptimeCheckTimingNodeRow(
+ props: TraceRowProps
+) {
+ const icon = ;
+
+ return (
+
+ props.tabIndex === 0
+ ? maybeFocusTraceRow(r, props.node, props.previouslyFocusedNodeRef)
+ : undefined
+ }
+ tabIndex={props.tabIndex}
+ className={`TraceRow ${props.rowSearchClassName} ${props.node.hasErrors ? props.node.maxIssueSeverity : ''}`}
+ onPointerDown={props.onRowClick}
+ onKeyDown={props.onRowKeyDown}
+ style={props.style}
+ >
+
+
+
+
+ {props.node.children.length > 0 || props.node.canFetchChildren ? (
+
+ )
+ }
+ status={props.node.fetchStatus}
+ expanded={props.node.expanded || props.node.hasFetchedChildren}
+ onDoubleClick={props.onExpandDoubleClick}
+ onClick={e =>
+ props.node.canFetchChildren ? props.onZoomIn(e) : props.onExpand(e)
+ }
+ >
+ {props.node.children.length > 0
+ ? TRACE_COUNT_FORMATTER.format(props.node.children.length)
+ : null}
+
+ ) : null}
+
+ {icon}
+
+ {props.node.value.op && props.node.value.op !== 'default' && (
+
+ {props.node.value.op}
+ —
+
+ )}
+
+ {props.node.description
+ ? ellipsize(props.node.description, 100)
+ : (props.node.id ?? 'unknown')}
+
+
+
+
+
+
+
+
+
+ );
+}
From dfe2925b422a086c0015bcaa879cc45ccae5871a Mon Sep 17 00:00:00 2001
From: Abdullah Khan
Date: Sat, 6 Dec 2025 13:36:16 -0500
Subject: [PATCH 2/2] feat(trace-tree-node): Fixing knip errors
---
.../views/performance/newTraceDetails/traceGuards.tsx | 9 ---------
.../newTraceDetails/traceModels/traceTree.spec.tsx | 11 ++++++++++-
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/static/app/views/performance/newTraceDetails/traceGuards.tsx b/static/app/views/performance/newTraceDetails/traceGuards.tsx
index af3de4cef3a7d9..7154903cf9728e 100644
--- a/static/app/views/performance/newTraceDetails/traceGuards.tsx
+++ b/static/app/views/performance/newTraceDetails/traceGuards.tsx
@@ -11,7 +11,6 @@ import type {SiblingAutogroupNode} from './traceModels/traceTreeNode/siblingAuto
import type {SpanNode} from './traceModels/traceTreeNode/spanNode';
import type {TransactionNode} from './traceModels/traceTreeNode/transactionNode';
import type {UptimeCheckNode} from './traceModels/traceTreeNode/uptimeCheckNode';
-import type {UptimeCheckTimingNode} from './traceModels/traceTreeNode/uptimeCheckTimingNode';
export function isMissingInstrumentationNode(
node: BaseNode
@@ -47,14 +46,6 @@ export function isUptimeCheckNode(node: BaseNode): node is UptimeCheckNode {
return isUptimeCheck(node.value);
}
-export function isUptimeCheckTimingNode(node: BaseNode): node is UptimeCheckTimingNode {
- return !!(
- node.value &&
- 'event_type' in node.value &&
- node.value.event_type === 'uptime_check_timing'
- );
-}
-
export function isTransactionNode(node: BaseNode): node is TransactionNode {
return !!(node.value && 'transaction.op' in node.value);
}
diff --git a/static/app/views/performance/newTraceDetails/traceModels/traceTree.spec.tsx b/static/app/views/performance/newTraceDetails/traceModels/traceTree.spec.tsx
index a4c8eaf92ea463..2d2a77ba1befd0 100644
--- a/static/app/views/performance/newTraceDetails/traceModels/traceTree.spec.tsx
+++ b/static/app/views/performance/newTraceDetails/traceModels/traceTree.spec.tsx
@@ -10,11 +10,12 @@ import {
isSpanNode,
isTransactionNode,
isUptimeCheckNode,
- isUptimeCheckTimingNode,
} from './../traceGuards';
+import type {BaseNode} from './traceTreeNode/baseNode';
import type {EapSpanNode} from './traceTreeNode/eapSpanNode';
import type {ParentAutogroupNode} from './traceTreeNode/parentAutogroupNode';
import type {SiblingAutogroupNode} from './traceTreeNode/siblingAutogroupNode';
+import type {UptimeCheckTimingNode} from './traceTreeNode/uptimeCheckTimingNode';
import {TraceShape, TraceTree} from './traceTree';
import {
assertEAPSpanNode,
@@ -2043,6 +2044,14 @@ describe('TraceTree', () => {
});
describe('uptime check integration', () => {
+ function isUptimeCheckTimingNode(node: BaseNode): node is UptimeCheckTimingNode {
+ return !!(
+ node.value &&
+ 'event_type' in node.value &&
+ node.value.event_type === 'uptime_check_timing'
+ );
+ }
+
it('automatically creates timing nodes when uptime check node is created', () => {
const uptimeCheck = makeUptimeCheck({
additional_attributes: {