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: {