From b206b45aa3e034961ac8971f09346e8dae7aeaf3 Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Wed, 2 Sep 2026 17:09:04 +0200 Subject: [PATCH 1/3] chore(deps): bump @sentry/* to 11.0.0-alpha.2 Spike to surface JS v11 compatibility issues via CI. Bumps first-party @sentry/* dependencies (browser, core, react, bundler-plugins, eslint-plugin-sdk, typescript) to 11.0.0-alpha.2 across core and the sample/e2e apps, and adapts the SDK source to the v11 breaking changes: - spanToJSON() now returns the streamed shape; switched the internals that need the classic SpanJSON to spanToStaticSpanJSON(). - inboundFiltersIntegration -> eventFiltersIntegration (re-exported under the RN public name). - AI instrumentation (OpenAI/Anthropic/GenAI/LangChain/LangGraph) moved to server-only @sentry/server-utils; dropped those re-exports. - SEMANTIC_ATTRIBUTE_SENTRY_SOURCE -> SENTRY_SEGMENT_NAME_SOURCE alias. - ExtendedError / User index signatures tightened to unknown; narrowed the affected call sites. - enableLogs and sendDefaultPii are now RN-owned options (core removed them / RN Omits dataCollection); cast getOptions() accordingly. - Test harness migrated off the removed Scope.clear() via a clearAllScopes() helper in test/testutils.ts. Local: yarn build compiles clean. Known remaining test failures are tracked as follow-ups (old span shape in assertions, obsolete AI export test, measurements investigation). Co-Authored-By: Claude Opus 4.8 --- dev-packages/e2e-tests/package.json | 2 +- packages/core/package.json | 12 +- .../core/src/js/feedback/FeedbackForm.tsx | 5 +- packages/core/src/js/index.ts | 30 +- packages/core/src/js/integrations/deeplink.ts | 3 +- packages/core/src/js/integrations/exports.ts | 4 +- .../src/js/integrations/nativelinkederrors.ts | 21 +- .../src/js/integrations/turboModuleContext.ts | 6 +- packages/core/src/js/options.ts | 11 + packages/core/src/js/replay/xhrUtils.ts | 12 +- packages/core/src/js/tracing/expoRouter.ts | 3 +- .../js/tracing/expoRouterErrorBoundary.tsx | 7 +- .../src/js/tracing/integrations/appStart.ts | 11 +- .../js/tracing/integrations/nativeFrames.ts | 6 +- .../js/tracing/integrations/stalltracking.ts | 6 +- .../tracing/integrations/userInteraction.ts | 10 +- .../core/src/js/tracing/onSpanEndUtils.ts | 24 +- .../src/js/tracing/reactnativenavigation.ts | 6 +- .../core/src/js/tracing/reactnavigation.ts | 13 +- .../core/src/js/tracing/semanticAttributes.ts | 4 +- packages/core/src/js/tracing/span.ts | 12 +- .../core/src/js/tracing/timetodisplay.tsx | 42 +-- packages/core/src/js/tracing/utils.ts | 8 +- packages/core/test/feedback.test.ts | 3 +- .../test/integrations/expocontext.test.ts | 5 +- .../expoupdateslistener.integration.test.ts | 5 +- .../integrations/expoupdateslistener.test.ts | 5 +- .../test/integrations/featureFlags.test.ts | 5 +- .../turboModuleContext.spans.test.ts | 5 +- packages/core/test/mocks/client.ts | 16 +- packages/core/test/testutils.ts | 68 ++++- .../tracing/integrations/appStart.test.ts | 50 +--- .../tracing/integrations/nativeframes.test.ts | 12 +- .../stallTracking/stalltracking.test.ts | 9 +- .../tracing/reactnativenavigation.test.ts | 5 +- .../reactnavigation.stalltracking.test.ts | 5 +- .../core/test/tracing/reactnavigation.test.ts | 5 +- .../core/test/tracing/timetodisplay.test.tsx | 14 +- samples/expo/package.json | 4 +- samples/react-native-macos/package.json | 4 +- samples/react-native/package.json | 6 +- yarn.lock | 275 +++++++----------- 42 files changed, 360 insertions(+), 399 deletions(-) diff --git a/dev-packages/e2e-tests/package.json b/dev-packages/e2e-tests/package.json index d01d0abc8f..b25c6458d7 100644 --- a/dev-packages/e2e-tests/package.json +++ b/dev-packages/e2e-tests/package.json @@ -13,7 +13,7 @@ "devDependencies": { "@babel/preset-env": "^7.25.3", "@babel/preset-typescript": "^7.18.6", - "@sentry/core": "10.73.0", + "@sentry/core": "11.0.0-alpha.2", "@sentry/react-native": "8.24.0", "@types/node": "^20.9.3", "@types/react": "^19.1.4", diff --git a/packages/core/package.json b/packages/core/package.json index da8ebf7598..33596bdd57 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -73,12 +73,12 @@ "react-native": ">=0.65.0" }, "dependencies": { - "@sentry/browser": "10.73.0", - "@sentry/bundler-plugins": "10.73.0", + "@sentry/browser": "11.0.0-alpha.2", + "@sentry/bundler-plugins": "11.0.0-alpha.2", "@sentry/cli": "3.7.0", - "@sentry/core": "10.73.0", + "@sentry/core": "11.0.0-alpha.2", "@sentry/expo-upload-sourcemaps": "workspace:*", - "@sentry/react": "10.73.0" + "@sentry/react": "11.0.0-alpha.2" }, "devDependencies": { "@babel/core": "^7.26.7", @@ -87,8 +87,8 @@ "@mswjs/interceptors": "^0.25.15", "@react-native/babel-preset": "0.87.1", "@react-native/jest-preset": "0.87.1", - "@sentry/eslint-plugin-sdk": "10.73.0", - "@sentry/typescript": "10.73.0", + "@sentry/eslint-plugin-sdk": "11.0.0-alpha.2", + "@sentry/typescript": "11.0.0-alpha.2", "@sentry/wizard": "7.0.3", "@testing-library/react-native": "^13.2.2", "@types/jest": "^29.5.13", diff --git a/packages/core/src/js/feedback/FeedbackForm.tsx b/packages/core/src/js/feedback/FeedbackForm.tsx index 1b221c7f81..d6e7ff86ac 100644 --- a/packages/core/src/js/feedback/FeedbackForm.tsx +++ b/packages/core/src/js/feedback/FeedbackForm.tsx @@ -62,7 +62,10 @@ export class FeedbackForm extends React.Component[0]); + } else if (isPlainObject(linkedError) && 'stackReturnAddresses' in linkedError) { // isObjCException - const { appleException, appleDebugImages } = exceptionFromAppleStackReturnAddresses(linkedError); + const { appleException, appleDebugImages } = exceptionFromAppleStackReturnAddresses( + linkedError as Parameters[0], + ); exception = appleException; exceptionDebugImages = appleDebugImages; } else if (isInstanceOf(linkedError, Error)) { - exception = exceptionFromError(parser, error[key]); + exception = exceptionFromError(parser, linkedError); } else if (isPlainObject(linkedError)) { - // oxlint-disable-next-line typescript-eslint(no-unnecessary-type-assertion) - const plainError = linkedError as Record; + const plainError = linkedError; exception = { type: typeof plainError.name === 'string' ? plainError.name : undefined, value: typeof plainError.message === 'string' ? plainError.message : undefined, @@ -122,7 +127,7 @@ function walkErrorTree( return walkErrorTree( parser, limit, - linkedError, + linkedError as ExtendedError, key, [...exceptions, exception], [...debugImages, ...(exceptionDebugImages || [])], diff --git a/packages/core/src/js/integrations/turboModuleContext.ts b/packages/core/src/js/integrations/turboModuleContext.ts index d2c16c5f15..8ed577cd68 100644 --- a/packages/core/src/js/integrations/turboModuleContext.ts +++ b/packages/core/src/js/integrations/turboModuleContext.ts @@ -1,7 +1,7 @@ /* oxlint-disable eslint(max-lines) */ import type { Client, Event, Integration, Span, TransactionEvent } from '@sentry/core'; -import { addBreadcrumb, debug, spanToJSON } from '@sentry/core'; +import { addBreadcrumb, debug, spanToStaticSpanJSON } from '@sentry/core'; import { addTurboModuleCallStartObserver, @@ -438,7 +438,7 @@ function attachWindowToSpan( window.writtenPerMethodKeys = nextKeys; if (rows.length > topN) { - const spanId = spanToJSON(span).span_id; + const spanId = spanToStaticSpanJSON(span).span_id; debug.log( `[TurboModuleContext] Span ${spanId ?? '(unknown)'} touched ${rows.length} unique TurboModule methods, ` + `truncated to top ${topN} by duration. Summary attributes still reflect the full totals.`, @@ -447,7 +447,7 @@ function attachWindowToSpan( span.setAttributes(attributes); - const spanId = spanToJSON(span).span_id; + const spanId = spanToStaticSpanJSON(span).span_id; if (spanId) { if (!pendingSpanAttributes.has(spanId) && pendingSpanAttributes.size >= MAX_PENDING_SPAN_ATTRIBUTES) { const oldest = pendingSpanAttributes.keys().next().value; diff --git a/packages/core/src/js/options.ts b/packages/core/src/js/options.ts index 3780539caf..dd847311b7 100644 --- a/packages/core/src/js/options.ts +++ b/packages/core/src/js/options.ts @@ -510,6 +510,17 @@ export interface BaseReactNativeOptions { */ propagateTraceparent?: boolean; + /** + * Enables sending log events to Sentry. + * + * On the JavaScript layer this used to be a `@sentry/core` option. As of JS SDK v11 the option + * was removed from core (logs are captured on-usage there), so the React Native SDK owns it to + * keep gating native log capture and its `logsOrigin` orchestration. + * + * @default false + */ + enableLogs?: boolean; + /** * Controls which log origin is captured when `enableLogs` is set to true. * 'all' will log all origins. diff --git a/packages/core/src/js/replay/xhrUtils.ts b/packages/core/src/js/replay/xhrUtils.ts index 81a805024f..f227f74d80 100644 --- a/packages/core/src/js/replay/xhrUtils.ts +++ b/packages/core/src/js/replay/xhrUtils.ts @@ -1,9 +1,19 @@ -import type { Breadcrumb, BreadcrumbHint, SentryWrappedXMLHttpRequest, XhrBreadcrumbHint } from '@sentry/core'; +import type { Breadcrumb, BreadcrumbHint, XhrBreadcrumbHint } from '@sentry/core'; import { dropUndefinedKeys } from '@sentry/core'; import type { NetworkBody, RequestBody, ResolvedNetworkOptions } from './networkUtils'; +// `SentryWrappedXMLHttpRequest` / `SentryXhrData` were removed from `@sentry/core` in +// JS v11. Declare the subset this module relies on locally. +interface SentryXhrData { + request_headers: Record; +} + +interface SentryWrappedXMLHttpRequest { + __sentry_xhr_v3__?: SentryXhrData; +} + import { decodeUtf8, filterHeaders, diff --git a/packages/core/src/js/tracing/expoRouter.ts b/packages/core/src/js/tracing/expoRouter.ts index 2394919287..5b7646ea4f 100644 --- a/packages/core/src/js/tracing/expoRouter.ts +++ b/packages/core/src/js/tracing/expoRouter.ts @@ -2,6 +2,7 @@ import { addBreadcrumb, getClient, SPAN_STATUS_ERROR, SPAN_STATUS_OK, startInact import { SPAN_ORIGIN_AUTO_EXPO_ROUTER_NAVIGATION, SPAN_ORIGIN_AUTO_EXPO_ROUTER_PREFETCH } from './origin'; import { clearPendingExpoRouterNavigation, setPendingExpoRouterNavigation } from './pendingExpoRouterNavigation'; +import type { ReactNativeClientOptions } from '../options'; type ExpoRouterHref = string | { pathname?: string; params?: Record }; @@ -239,5 +240,5 @@ function serializeHref(href: unknown): string { } function isSendDefaultPiiEnabled(): boolean { - return getClient()?.getOptions()?.sendDefaultPii ?? false; + return (getClient()?.getOptions() as ReactNativeClientOptions | undefined)?.sendDefaultPii ?? false; } diff --git a/packages/core/src/js/tracing/expoRouterErrorBoundary.tsx b/packages/core/src/js/tracing/expoRouterErrorBoundary.tsx index 089f9ffab6..9631667d01 100644 --- a/packages/core/src/js/tracing/expoRouterErrorBoundary.tsx +++ b/packages/core/src/js/tracing/expoRouterErrorBoundary.tsx @@ -9,12 +9,13 @@ import { getClient, getRootSpan, SPAN_STATUS_ERROR, - spanToJSON, + spanToStaticSpanJSON, } from '@sentry/core'; import * as React from 'react'; import { registerFeatureMarker } from '../utils/featureMarkers'; import { getCurrentExpoRouterRouteInfo } from './expoRouterStore'; +import type { ReactNativeClientOptions } from '../options'; export const EXPO_ROUTER_ERROR_BOUNDARY_INTEGRATION_NAME = 'ExpoRouterErrorBoundary'; @@ -110,7 +111,7 @@ export function wrapExpoRouterErrorBoundary

{ let childEndFramesPromise: Promise | undefined; if (!isRootSpan(span)) { const rootSpanId = getRootSpan(span).spanContext().spanId; - const spanTimestamp = spanToJSON(span).timestamp; + const spanTimestamp = spanToStaticSpanJSON(span).timestamp; if (spanTimestamp) { childEndFramesPromise = fetchNativeFrames(); _lastChildSpanEndFramesByRootSpan.set( @@ -195,7 +195,7 @@ export const nativeFramesIntegration = (): Integration => { `[${INTEGRATION_NAME}] Attached frame data to span ${spanId}: total=${totalFrames}, slow=${slowFrames}, frozen=${frozenFrames}`, ); - const spanJson = spanToJSON(span); + const spanJson = spanToStaticSpanJSON(span); if (spanJson.start_timestamp && spanJson.timestamp) { try { const delay = await fetchNativeFramesDelay(spanJson.start_timestamp, spanJson.timestamp); diff --git a/packages/core/src/js/tracing/integrations/stalltracking.ts b/packages/core/src/js/tracing/integrations/stalltracking.ts index 2453afd011..d5fd24b6b3 100644 --- a/packages/core/src/js/tracing/integrations/stalltracking.ts +++ b/packages/core/src/js/tracing/integrations/stalltracking.ts @@ -1,7 +1,7 @@ import type { Client, Integration, Measurements, MeasurementUnit, Span } from '@sentry/core'; import type { AppStateStatus } from 'react-native'; -import { debug, getRootSpan, spanIsSampled, spanToJSON, timestampInSeconds } from '@sentry/core'; +import { debug, getRootSpan, spanIsSampled, spanToStaticSpanJSON, timestampInSeconds } from '@sentry/core'; import { AppState } from 'react-native'; import { STALL_COUNT, STALL_LONGEST_TIME, STALL_TOTAL_TIME } from '../../measurements'; @@ -163,7 +163,7 @@ export const stallTrackingIntegration = ({ // The endTimestamp is always set, but type-wise it's optional // https://github.com/getsentry/sentry-javascript/blob/38bd57b0785c97c413f36f89ff931d927e469078/packages/core/src/tracing/sentrySpan.ts#L170 - const endTimestamp = spanToJSON(rootSpan).timestamp; + const endTimestamp = spanToStaticSpanJSON(rootSpan).timestamp; let statsOnFinish: StallMeasurements | undefined; if (isNearToNow(endTimestamp)) { @@ -232,7 +232,7 @@ export const stallTrackingIntegration = ({ const _onChildSpanEnd = (childSpan: Span): void => { const rootSpan = getRootSpan(childSpan); - const finalEndTimestamp = spanToJSON(childSpan).timestamp; + const finalEndTimestamp = spanToStaticSpanJSON(childSpan).timestamp; if (finalEndTimestamp) { _markSpanFinish(rootSpan, finalEndTimestamp); } diff --git a/packages/core/src/js/tracing/integrations/userInteraction.ts b/packages/core/src/js/tracing/integrations/userInteraction.ts index c1fbf3a48c..551c05af78 100644 --- a/packages/core/src/js/tracing/integrations/userInteraction.ts +++ b/packages/core/src/js/tracing/integrations/userInteraction.ts @@ -6,7 +6,7 @@ import { getClient, getCurrentScope, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - spanToJSON, + spanToStaticSpanJSON, } from '@sentry/core'; import type { ReactNativeClientOptions } from '../../options'; @@ -63,7 +63,7 @@ export const startUserInteractionSpan = (userInteractionId: { if (activeTransaction && activeTransactionIsNotInteraction) { debug.warn( `[${INTEGRATION_NAME}] Did not create ${op} transaction because active transaction ${ - spanToJSON(activeTransaction).description + spanToStaticSpanJSON(activeTransaction).description } exists on the scope.`, ); return undefined; @@ -72,12 +72,12 @@ export const startUserInteractionSpan = (userInteractionId: { const name = `${tracing.state.currentRoute}.${elementId}`; if ( activeTransaction && - spanToJSON(activeTransaction).description === name && - spanToJSON(activeTransaction).op === op + spanToStaticSpanJSON(activeTransaction).description === name && + spanToStaticSpanJSON(activeTransaction).op === op ) { debug.warn( `[${INTEGRATION_NAME}] Did not create ${op} transaction because it the same transaction ${ - spanToJSON(activeTransaction).description + spanToStaticSpanJSON(activeTransaction).description } already exists on the scope.`, ); return undefined; diff --git a/packages/core/src/js/tracing/onSpanEndUtils.ts b/packages/core/src/js/tracing/onSpanEndUtils.ts index aa61b08735..601718b568 100644 --- a/packages/core/src/js/tracing/onSpanEndUtils.ts +++ b/packages/core/src/js/tracing/onSpanEndUtils.ts @@ -1,7 +1,7 @@ import type { Client, Event, Span } from '@sentry/core'; import type { AppStateStatus } from 'react-native'; -import { debug, getSpanDescendants, SPAN_STATUS_ERROR, spanToJSON, timestampInSeconds } from '@sentry/core'; +import { debug, getSpanDescendants, SPAN_STATUS_ERROR, spanToStaticSpanJSON, timestampInSeconds } from '@sentry/core'; import { AppState, Platform } from 'react-native'; import { isRootSpan, isSentrySpan } from '../utils/span'; @@ -38,7 +38,7 @@ export function markRootSpanForDiscard(span: Span, reason: SentryDiscardReason): * Returns the SDK-side discard reason recorded on a root span, if any. */ export function getRootSpanDiscardReason(span: Span): SentryDiscardReason | undefined { - const value = spanToJSON(span).data?.[SENTRY_DISCARD_REASON_ATTRIBUTE]; + const value = spanToStaticSpanJSON(span).data?.[SENTRY_DISCARD_REASON_ATTRIBUTE]; return typeof value === 'string' ? (value as SentryDiscardReason) : undefined; } @@ -81,8 +81,8 @@ export const adjustTransactionDuration = (client: Client, span: Span, maxDuratio } unsubscribe(); - const endTimestamp = spanToJSON(span).timestamp; - const startTimestamp = spanToJSON(span).start_timestamp; + const endTimestamp = spanToStaticSpanJSON(span).timestamp; + const startTimestamp = spanToStaticSpanJSON(span).start_timestamp; if (!endTimestamp || !startTimestamp) { return; } @@ -106,8 +106,8 @@ function getMeaningfulChildSpans(span: Span): Span[] { return children.filter( child => child.spanContext().spanId !== span.spanContext().spanId && - spanToJSON(child).op !== 'ui.load.initial_display' && - spanToJSON(child).op !== 'navigation.processing', + spanToStaticSpanJSON(child).op !== 'ui.load.initial_display' && + spanToStaticSpanJSON(child).op !== 'navigation.processing', ); } @@ -157,7 +157,7 @@ export const ignoreEmptyBackNavigation = (client: Client | undefined, span: Span client, span, // Only discard if route has been seen before - span => spanToJSON(span).data?.['route.has_been_seen'] === true, + span => spanToStaticSpanJSON(span).data?.['route.has_been_seen'] === true, // Log message and mark the span for discard via the event processor. span => { debug.log( @@ -190,7 +190,7 @@ export const ignoreEmptyRouteChangeTransactions = ( // 2. No route information was set // 3. Still being tracked (state listener never called) span => { - const spanJSON = spanToJSON(span); + const spanJSON = spanToStaticSpanJSON(span); return ( spanJSON.description === defaultNavigationSpanName && !spanJSON.data?.['route.name'] && isSpanStillTracked() ); @@ -226,7 +226,7 @@ export const onlySampleIfChildSpans = (client: Client, span: Span): void => { if (children.length <= 1) { // Span always has at lest one child, itself - debug.log(`Not sampling as ${spanToJSON(span).op} transaction has no child spans.`); + debug.log(`Not sampling as ${spanToStaticSpanJSON(span).op} transaction has no child spans.`); markRootSpanForDiscard(span, 'no_child_spans'); } }); @@ -256,7 +256,7 @@ export const cancelInBackground = (client: Client, span: Span): void => { clearTimeout(inactiveTimeout); inactiveTimeout = undefined; } - debug.log(`Setting ${spanToJSON(span).op} transaction to cancelled because the app is in the background.`); + debug.log(`Setting ${spanToStaticSpanJSON(span).op} transaction to cancelled because the app is in the background.`); // End still-recording http.client children at the time the app left // the foreground, not when the deferred timer fires. On iOS, the JS @@ -266,7 +266,7 @@ export const cancelInBackground = (client: Client, span: Span): void => { const childEndTimestamp = leftForegroundTimestamp ?? timestampInSeconds(); const children = getSpanDescendants(span); for (const child of children) { - if (child !== span && child.isRecording() && spanToJSON(child).op === 'http.client') { + if (child !== span && child.isRecording() && spanToStaticSpanJSON(child).op === 'http.client') { child.setStatus({ code: SPAN_STATUS_ERROR, message: 'cancelled' }); child.end(childEndTimestamp); } @@ -305,7 +305,7 @@ export const cancelInBackground = (client: Client, span: Span): void => { return; } unsubscribe(); - debug.log(`Removing AppState listener for ${spanToJSON(span).op} transaction.`); + debug.log(`Removing AppState listener for ${spanToStaticSpanJSON(span).op} transaction.`); if (inactiveTimeout !== undefined) { clearTimeout(inactiveTimeout); inactiveTimeout = undefined; diff --git a/packages/core/src/js/tracing/reactnativenavigation.ts b/packages/core/src/js/tracing/reactnativenavigation.ts index e93909ce8d..eafe79fe95 100644 --- a/packages/core/src/js/tracing/reactnativenavigation.ts +++ b/packages/core/src/js/tracing/reactnativenavigation.ts @@ -5,8 +5,8 @@ import { getClient, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, - spanToJSON, + SENTRY_SEGMENT_NAME_SOURCE as SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, + spanToStaticSpanJSON, } from '@sentry/core'; import type { EmitterSubscription } from '../utils/rnlibrariesinterface'; @@ -175,7 +175,7 @@ export const reactNativeNavigationIntegration = ({ const routeHasBeenSeen = recentComponentIds.includes(event.componentId); - if (spanToJSON(latestNavigationSpan).description === DEFAULT_NAVIGATION_SPAN_NAME) { + if (spanToStaticSpanJSON(latestNavigationSpan).description === DEFAULT_NAVIGATION_SPAN_NAME) { latestNavigationSpan.updateName(event.componentName); } latestNavigationSpan.setAttributes({ diff --git a/packages/core/src/js/tracing/reactnavigation.ts b/packages/core/src/js/tracing/reactnavigation.ts index 507773a914..87c41e2b75 100644 --- a/packages/core/src/js/tracing/reactnavigation.ts +++ b/packages/core/src/js/tracing/reactnavigation.ts @@ -9,7 +9,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_STATUS_OK, - spanToJSON, + spanToStaticSpanJSON, startInactiveSpan, timestampInSeconds, } from '@sentry/core'; @@ -46,6 +46,8 @@ import { } from './span'; import { addTimeToInitialDisplayFallback } from './timeToDisplayFallback'; +import type { ReactNativeClientOptions } from '../options'; + export const INTEGRATION_NAME = 'ReactNavigation'; const NAVIGATION_HISTORY_MAX_SIZE = 200; @@ -655,7 +657,7 @@ export const reactNavigationIntegration = ({ navigationProcessingSpan = startInactiveSpan({ op: 'navigation.processing', name: 'Navigation dispatch to navigation cancelled or screen mounted', - startTime: spanToJSON(latestNavigationSpan).start_timestamp, + startTime: spanToStaticSpanJSON(latestNavigationSpan).start_timestamp, }); navigationProcessingSpan.setAttribute( SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, @@ -813,7 +815,7 @@ export const reactNavigationIntegration = ({ if (!latestNavigationSpanNameCustomized) { latestNavigationSpan.updateName(routeName); } - const sendDefaultPii = getClient()?.getOptions()?.sendDefaultPii ?? false; + const sendDefaultPii = (getClient()?.getOptions() as ReactNativeClientOptions | undefined)?.sendDefaultPii ?? false; latestNavigationSpan.setAttributes({ 'route.name': routeName, 'route.key': route.key, @@ -945,7 +947,8 @@ function tagSpanWithDeepLink(span: Span, link: PendingDeepLink): boolean { } taggedDeepLinkSpans.add(span); - const sendDefaultPii = getClient()?.getOptions()?.sendDefaultPii ?? false; + const sendDefaultPii = + (getClient()?.getOptions() as ReactNativeClientOptions | undefined)?.sendDefaultPii ?? false; const url = sendDefaultPii ? link.url : sanitizeDeepLinkUrl(link.url); span.setAttributes({ @@ -961,7 +964,7 @@ function tagSpanWithDeepLink(span: Span, link: PendingDeepLink): boolean { /** Returns true if the span is still recording (has not been ended). */ function isSpanRecording(span: Span): boolean { - return spanToJSON(span).timestamp === undefined; + return spanToStaticSpanJSON(span).timestamp === undefined; } /** diff --git a/packages/core/src/js/tracing/semanticAttributes.ts b/packages/core/src/js/tracing/semanticAttributes.ts index 1e7d3b4474..11592dc1fe 100644 --- a/packages/core/src/js/tracing/semanticAttributes.ts +++ b/packages/core/src/js/tracing/semanticAttributes.ts @@ -1,5 +1,7 @@ export { - SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, + // `SEMANTIC_ATTRIBUTE_SENTRY_SOURCE` (`sentry.source`) was removed in JS v11. + // Its replacement is `SENTRY_SEGMENT_NAME_SOURCE` (`sentry.segment.name.source`). + SENTRY_SEGMENT_NAME_SOURCE as SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, diff --git a/packages/core/src/js/tracing/span.ts b/packages/core/src/js/tracing/span.ts index 7b9188224a..0704815cf3 100644 --- a/packages/core/src/js/tracing/span.ts +++ b/packages/core/src/js/tracing/span.ts @@ -10,7 +10,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SentryNonRecordingSpan, SPAN_STATUS_ERROR, - spanToJSON, + spanToStaticSpanJSON, startIdleSpan as coreStartIdleSpan, } from '@sentry/core'; import { AppState, Platform } from 'react-native'; @@ -70,14 +70,14 @@ export const startIdleNavigationSpan = ( if (isActiveSpanInteraction && isAppRestart) { debug.log( `[startIdleNavigationSpan] Not canceling ${ - spanToJSON(activeSpan).op + spanToStaticSpanJSON(activeSpan).op } transaction because navigation is from app restart - preserving error context.`, ); // Don't end the span - it will timeout naturally and remains available for error/replay processing } else if (isActiveSpanInteraction) { debug.log( `[startIdleNavigationSpan] Canceling ${ - spanToJSON(activeSpan).op + spanToStaticSpanJSON(activeSpan).op } transaction because of a new navigation root span.`, ); activeSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'cancelled' }); @@ -150,7 +150,7 @@ export function getDefaultIdleNavigationSpanOptions(): StartSpanOptions { * Checks if the span is a Sentry User Interaction span. */ export function isSentryInteractionSpan(span: Span): boolean { - return [SPAN_ORIGIN_AUTO_INTERACTION, SPAN_ORIGIN_MANUAL_INTERACTION].includes(spanToJSON(span).origin || ''); + return [SPAN_ORIGIN_AUTO_INTERACTION, SPAN_ORIGIN_MANUAL_INTERACTION].includes(spanToStaticSpanJSON(span).origin || ''); } export const SCOPE_SPAN_FIELD = '_sentrySpan'; @@ -172,7 +172,7 @@ export function clearActiveSpanFromScope(scope: ScopeWithMaybeSpan): void { */ export function addDefaultOpForSpanFrom(client: Client): void { client.on('spanStart', (span: Span) => { - if (!spanToJSON(span).op) { + if (!spanToStaticSpanJSON(span).op) { span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'default'); } }); @@ -188,7 +188,7 @@ export const SPAN_THREAD_NAME_JAVASCRIPT = 'javascript'; */ export function addThreadInfoToSpan(client: Client): void { client.on('spanStart', (span: Span) => { - if (!spanToJSON(span).data?.[SPAN_THREAD_NAME]) { + if (!spanToStaticSpanJSON(span).data?.[SPAN_THREAD_NAME]) { span.setAttribute(SPAN_THREAD_NAME, SPAN_THREAD_NAME_JAVASCRIPT); } }); diff --git a/packages/core/src/js/tracing/timetodisplay.tsx b/packages/core/src/js/tracing/timetodisplay.tsx index 112b90afa1..3feb934684 100644 --- a/packages/core/src/js/tracing/timetodisplay.tsx +++ b/packages/core/src/js/tracing/timetodisplay.tsx @@ -10,7 +10,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_STATUS_ERROR, SPAN_STATUS_OK, - spanToJSON, + spanToStaticSpanJSON, startInactiveSpan, timestampInSeconds, } from '@sentry/core'; @@ -82,7 +82,7 @@ export function TimeToInitialDisplay(props: TimeToDisplayProps): React.ReactElem manualInitialDisplaySpans.set(activeSpan, true); } - const parentSpanId = activeSpan && spanToJSON(activeSpan).span_id; + const parentSpanId = activeSpan && spanToStaticSpanJSON(activeSpan).span_id; const initialDisplay = useCoordinatedDisplay('ttid', parentSpanId, props); return ( @@ -101,7 +101,7 @@ export function TimeToInitialDisplay(props: TimeToDisplayProps): React.ReactElem */ export function TimeToFullDisplay(props: TimeToDisplayProps): React.ReactElement { const activeSpan = getActiveSpan(); - const parentSpanId = activeSpan && spanToJSON(activeSpan).span_id; + const parentSpanId = activeSpan && spanToStaticSpanJSON(activeSpan).span_id; const fullDisplay = useCoordinatedDisplay('ttfd', parentSpanId, props); return ( @@ -226,7 +226,7 @@ export function startTimeToInitialDisplaySpan( return undefined; } - const existingSpan = getSpanDescendants(activeSpan).find(span => spanToJSON(span).op === 'ui.load.initial_display'); + const existingSpan = getSpanDescendants(activeSpan).find(span => spanToStaticSpanJSON(span).op === 'ui.load.initial_display'); if (existingSpan) { debug.log('[TimeToDisplay] Found existing ui.load.initial_display span.'); return existingSpan; @@ -235,7 +235,7 @@ export function startTimeToInitialDisplaySpan( const initialDisplaySpan = startInactiveSpan({ op: 'ui.load.initial_display', name: 'Time To Initial Display', - startTime: spanToJSON(activeSpan).start_timestamp, + startTime: spanToStaticSpanJSON(activeSpan).start_timestamp, ...options, }); @@ -284,13 +284,13 @@ export function startTimeToFullDisplaySpan( const descendantSpans = getSpanDescendants(activeSpan); - const initialDisplaySpan = descendantSpans.find(span => spanToJSON(span).op === 'ui.load.initial_display'); + const initialDisplaySpan = descendantSpans.find(span => spanToStaticSpanJSON(span).op === 'ui.load.initial_display'); if (!initialDisplaySpan) { debug.warn('[TimeToDisplay] No initial display span found to attach ui.load.full_display to.'); return undefined; } - const existingSpan = descendantSpans.find(span => spanToJSON(span).op === 'ui.load.full_display'); + const existingSpan = descendantSpans.find(span => spanToStaticSpanJSON(span).op === 'ui.load.full_display'); if (existingSpan) { debug.log('[TimeToDisplay] Found existing ui.load.full_display span.'); return existingSpan; @@ -299,7 +299,7 @@ export function startTimeToFullDisplaySpan( const fullDisplaySpan = startInactiveSpan({ op: 'ui.load.full_display', name: 'Time To Full Display', - startTime: spanToJSON(initialDisplaySpan).start_timestamp, + startTime: spanToStaticSpanJSON(initialDisplaySpan).start_timestamp, ...options, }); if (!fullDisplaySpan) { @@ -314,12 +314,12 @@ export function startTimeToFullDisplaySpan( }); const timeout = setTimeout(() => { - if (spanToJSON(fullDisplaySpan).timestamp) { + if (spanToStaticSpanJSON(fullDisplaySpan).timestamp) { return; } fullDisplaySpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'deadline_exceeded' }); - const fullDisplayEndTimestamp = spanToJSON(initialDisplaySpan).timestamp; + const fullDisplayEndTimestamp = spanToStaticSpanJSON(initialDisplaySpan).timestamp; captureEndFramesAndAttachToSpan(fullDisplaySpan, fullDisplayEndTimestamp) .then(() => { debug.log(`[TimeToDisplay] span ${fullDisplaySpan.spanContext().spanId} updated with frame data.`); @@ -330,7 +330,7 @@ export function startTimeToFullDisplaySpan( debug.warn( `[TimeToDisplay] Failed to capture end frames for full display span (${fullDisplaySpan.spanContext().spanId}).`, ); - fullDisplaySpan.end(spanToJSON(initialDisplaySpan).timestamp); + fullDisplaySpan.end(spanToStaticSpanJSON(initialDisplaySpan).timestamp); setSpanDurationAsMeasurement('time_to_full_display', fullDisplaySpan); }); @@ -377,13 +377,13 @@ export function updateInitialDisplaySpan( return; } - if (spanToJSON(span).parent_span_id !== spanToJSON(activeSpan).span_id) { + if (spanToStaticSpanJSON(span).parent_span_id !== spanToStaticSpanJSON(activeSpan).span_id) { debug.warn('[TimeToDisplay] Initial display span is not a child of current active span.'); return; } - if (spanToJSON(span).timestamp) { - debug.warn(`[TimeToDisplay] ${spanToJSON(span).description} span already ended.`); + if (spanToStaticSpanJSON(span).timestamp) { + debug.warn(`[TimeToDisplay] ${spanToStaticSpanJSON(span).description} span already ended.`); return; } @@ -391,7 +391,7 @@ export function updateInitialDisplaySpan( .then(() => { span.end(frameTimestampSeconds); span.setStatus({ code: SPAN_STATUS_OK }); - debug.log(`[TimeToDisplay] ${spanToJSON(span).description} span updated with end timestamp and frame data.`); + debug.log(`[TimeToDisplay] ${spanToStaticSpanJSON(span).description} span updated with end timestamp and frame data.`); if (fullDisplayBeforeInitialDisplay.has(activeSpan)) { fullDisplayBeforeInitialDisplay.delete(activeSpan); @@ -443,7 +443,7 @@ export function reportFullyDisplayed(): void { return; } const rootSpan = getRootSpan(activeSpan); - const rootSpanId = spanToJSON(rootSpan).span_id; + const rootSpanId = spanToStaticSpanJSON(rootSpan).span_id; if (rootSpanId && !_imperativeTtfdTimestamps.has(rootSpanId)) { if (_imperativeTtfdTimestamps.size >= MAX_IMPERATIVE_TTFD_ENTRIES) { const oldestKey = _imperativeTtfdTimestamps.keys().next().value; @@ -476,8 +476,8 @@ function updateFullDisplaySpan(frameTimestampSeconds: number, passedInitialDispl const existingInitialDisplaySpan = passedInitialDisplaySpan || - getSpanDescendants(activeSpan).find(span => spanToJSON(span).op === 'ui.load.initial_display'); - const initialDisplayEndTimestamp = existingInitialDisplaySpan && spanToJSON(existingInitialDisplaySpan).timestamp; + getSpanDescendants(activeSpan).find(span => spanToStaticSpanJSON(span).op === 'ui.load.initial_display'); + const initialDisplayEndTimestamp = existingInitialDisplaySpan && spanToStaticSpanJSON(existingInitialDisplaySpan).timestamp; if (!initialDisplayEndTimestamp) { fullDisplayBeforeInitialDisplay.set(activeSpan, true); debug.warn( @@ -494,7 +494,7 @@ function updateFullDisplaySpan(frameTimestampSeconds: number, passedInitialDispl return; } - const spanJSON = spanToJSON(span); + const spanJSON = spanToStaticSpanJSON(span); if (spanJSON.timestamp) { debug.warn(`[TimeToDisplay] ${spanJSON.description} (${spanJSON.span_id}) span already ended.`); return; @@ -678,10 +678,10 @@ async function captureEndFramesAndAttachToSpan(span: Span, spanEndTimestampSecon attachFrameDataToSpan(span, frameData.startFrames, endFrames); - const spanStartTimestamp = spanToJSON(span).start_timestamp; + const spanStartTimestamp = spanToStaticSpanJSON(span).start_timestamp; if (spanStartTimestamp) { try { - const endTimestamp = spanEndTimestampSeconds || spanToJSON(span).timestamp || Date.now() / 1000; + const endTimestamp = spanEndTimestampSeconds || spanToStaticSpanJSON(span).timestamp || Date.now() / 1000; const framesDelay = await Promise.race([ NATIVE.fetchNativeFramesDelay(spanStartTimestamp, endTimestamp), new Promise(resolve => setTimeout(() => resolve(null), FETCH_FRAMES_TIMEOUT_MS)), diff --git a/packages/core/src/js/tracing/utils.ts b/packages/core/src/js/tracing/utils.ts index 57f63cf336..19a6d43eeb 100644 --- a/packages/core/src/js/tracing/utils.ts +++ b/packages/core/src/js/tracing/utils.ts @@ -19,7 +19,7 @@ import { setMeasurement, SPAN_STATUS_ERROR, SPAN_STATUS_OK, - spanToJSON, + spanToStaticSpanJSON, startInactiveSpan, timestampInSeconds, uuid4, @@ -60,7 +60,7 @@ export function isNearToNow(timestamp: number | undefined): boolean { * Uses `setMeasurement` function from @sentry/core. */ export function setSpanDurationAsMeasurement(name: string, span: Span): void { - const { timestamp: spanEnd, start_timestamp: spanStart } = spanToJSON(span); + const { timestamp: spanEnd, start_timestamp: spanStart } = spanToStaticSpanJSON(span); if (!spanEnd || !spanStart) { return; } @@ -73,7 +73,7 @@ export function setSpanDurationAsMeasurement(name: string, span: Span): void { * Uses `setMeasurement` function from @sentry/core. */ export function setSpanDurationAsMeasurementOnSpan(name: string, span: Span, on: Span): void { - const { timestamp: spanEnd, start_timestamp: spanStart } = spanToJSON(span); + const { timestamp: spanEnd, start_timestamp: spanStart } = spanToStaticSpanJSON(span); if (!spanEnd || !spanStart) { return; } @@ -104,7 +104,7 @@ export function setSpanMeasurement(span: Span, key: string, value: number, unit: */ export function getLatestChildSpanEndTimestamp(span: Span): number | undefined { const childEndTimestamps = getSpanDescendants(span) - .map(span => spanToJSON(span).timestamp) + .map(span => spanToStaticSpanJSON(span).timestamp) .filter(timestamp => !!timestamp) as number[]; return childEndTimestamps.length ? Math.max(...childEndTimestamps) : undefined; diff --git a/packages/core/test/feedback.test.ts b/packages/core/test/feedback.test.ts index 37a2c37f33..a76dff6c51 100644 --- a/packages/core/test/feedback.test.ts +++ b/packages/core/test/feedback.test.ts @@ -12,11 +12,12 @@ import { } from '@sentry/core'; import { getDefaultTestClientOptions, TestClient } from './mocks/client'; +import { clearAllScopes } from './testutils'; describe('captureFeedback', () => { beforeEach(() => { getCurrentScope().setClient(undefined); - getCurrentScope().clear(); + clearAllScopes(); }); test('it works without a client', () => { diff --git a/packages/core/test/integrations/expocontext.test.ts b/packages/core/test/integrations/expocontext.test.ts index e12fa55aee..a9be538f8c 100644 --- a/packages/core/test/integrations/expocontext.test.ts +++ b/packages/core/test/integrations/expocontext.test.ts @@ -12,6 +12,7 @@ import { getExpoDevice } from '../../src/js/utils/expomodules'; import * as expoModules from '../../src/js/utils/expomodules'; import { setupTestClient, TestClient } from '../mocks/client'; import { NATIVE } from '../mockWrapper'; +import { clearAllScopes } from '../testutils'; jest.mock('../../src/js/wrapper', () => jest.requireActual('../mockWrapper')); jest.mock('../../src/js/utils/expomodules'); @@ -20,9 +21,7 @@ describe('Expo Context Integration', () => { afterEach(() => { jest.clearAllMocks(); - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); }); describe('Set Native Context after init()', () => { diff --git a/packages/core/test/integrations/expoupdateslistener.integration.test.ts b/packages/core/test/integrations/expoupdateslistener.integration.test.ts index b29ff63f4b..ce2d75c57b 100644 --- a/packages/core/test/integrations/expoupdateslistener.integration.test.ts +++ b/packages/core/test/integrations/expoupdateslistener.integration.test.ts @@ -5,6 +5,7 @@ import { getCurrentScope, getGlobalScope, getIsolationScope } from '@sentry/core import { handleSpanLifecycle } from '../../src/js/integrations/expoupdateslistener'; import { SPAN_ORIGIN_AUTO_EXPO_UPDATES } from '../../src/js/tracing/origin'; import { setupTestClient } from '../mocks/client'; +import { clearAllScopes } from '../testutils'; jest.mock('../../src/js/wrapper', () => jest.requireActual('../mockWrapper')); @@ -21,9 +22,7 @@ describe('ExpoUpdatesListener Integration (real spans)', () => { }; afterEach(() => { - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); }); it('check span produces a transaction with correct op, origin, and ok status', () => { diff --git a/packages/core/test/integrations/expoupdateslistener.test.ts b/packages/core/test/integrations/expoupdateslistener.test.ts index 243cf619f9..555c4d88c0 100644 --- a/packages/core/test/integrations/expoupdateslistener.test.ts +++ b/packages/core/test/integrations/expoupdateslistener.test.ts @@ -17,6 +17,7 @@ import { import { SPAN_ORIGIN_AUTO_EXPO_UPDATES } from '../../src/js/tracing/origin'; import * as environment from '../../src/js/utils/environment'; import { setupTestClient } from '../mocks/client'; +import { clearAllScopes } from '../testutils'; jest.mock('../../src/js/wrapper', () => jest.requireActual('../mockWrapper')); jest.mock('@sentry/core', () => { @@ -64,9 +65,7 @@ describe('ExpoUpdatesListener Integration', () => { isRestarting: false, }; - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); }); describe('setup', () => { diff --git a/packages/core/test/integrations/featureFlags.test.ts b/packages/core/test/integrations/featureFlags.test.ts index a30fc6b261..2587ef62b0 100644 --- a/packages/core/test/integrations/featureFlags.test.ts +++ b/packages/core/test/integrations/featureFlags.test.ts @@ -4,6 +4,7 @@ import { getCurrentScope } from '@sentry/core'; import { featureFlagsIntegration } from '../../src/js/integrations/featureFlags'; import { NATIVE } from '../../src/js/wrapper'; +import { clearAllScopes } from '../testutils'; jest.mock('../../src/js/wrapper'); @@ -12,12 +13,12 @@ describe('Feature Flags Integration', () => { beforeEach(() => { integration = featureFlagsIntegration(); - getCurrentScope().clear(); + clearAllScopes(); }); afterEach(() => { jest.clearAllMocks(); - getCurrentScope().clear(); + clearAllScopes(); }); it('registers under the shared FeatureFlags name', () => { diff --git a/packages/core/test/integrations/turboModuleContext.spans.test.ts b/packages/core/test/integrations/turboModuleContext.spans.test.ts index 3212bd39ea..1e38e04dbf 100644 --- a/packages/core/test/integrations/turboModuleContext.spans.test.ts +++ b/packages/core/test/integrations/turboModuleContext.spans.test.ts @@ -29,6 +29,7 @@ import { _resetTurboModuleAggregator } from '../../src/js/turbomodule/turboModul import { _resetTurboModuleTracker } from '../../src/js/turbomodule/turboModuleTracker'; import { _resetWrappedModules } from '../../src/js/turbomodule/wrapTurboModule'; import { getDefaultTestClientOptions, TestClient } from '../mocks/client'; +import { clearAllScopes } from '../testutils'; const SYNC_CALL_COUNT = 5; @@ -37,9 +38,7 @@ describe('turboModuleContextIntegration with real spans', () => { _resetTurboModuleTracker(); _resetTurboModuleAggregator(); _resetWrappedModules(); - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); }); afterEach(() => { diff --git a/packages/core/test/mocks/client.ts b/packages/core/test/mocks/client.ts index 8595bea471..c7de8339e5 100644 --- a/packages/core/test/mocks/client.ts +++ b/packages/core/test/mocks/client.ts @@ -1,17 +1,9 @@ import type { Event, EventHint, Integration, Outcome, ParameterizedString, Session, SeverityLevel } from '@sentry/core'; -import { - Client, - createTransport, - getCurrentScope, - getGlobalScope, - getIsolationScope, - initAndBind, - resolvedSyncPromise, - setCurrentClient, -} from '@sentry/core'; +import { Client, createTransport, initAndBind, resolvedSyncPromise, setCurrentClient } from '@sentry/core'; import type { ReactNativeClientOptions } from '../../src/js/options'; +import { clearAllScopes } from '../testutils'; export function getDefaultTestClientOptions(options: Partial = {}): TestClientOptions { return { @@ -106,9 +98,7 @@ export function init(options: TestClientOptions): void { } export function setupTestClient(options: Partial = {}): TestClient { - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); const finalOptions = getDefaultTestClientOptions({ tracesSampleRate: 1.0, ...options }); const client = new TestClient(finalOptions); diff --git a/packages/core/test/testutils.ts b/packages/core/test/testutils.ts index dc7eda9864..c6fe78d467 100644 --- a/packages/core/test/testutils.ts +++ b/packages/core/test/testutils.ts @@ -1,6 +1,13 @@ -import type { Session, Transport, UserFeedback } from '@sentry/core'; +import type { Scope, Session, Transport, UserFeedback } from '@sentry/core'; -import { rejectedSyncPromise } from '@sentry/core'; +import { + _INTERNAL_setSpanForScope, + generateTraceId, + getCurrentScope, + getGlobalScope, + getIsolationScope, + rejectedSyncPromise, +} from '@sentry/core'; export type MockInterface = { [K in keyof T]: T[K] extends (...args: infer A) => infer B ? jest.Mock : T[K]; @@ -73,3 +80,60 @@ export const secondAgoTimestampMs = (): number => { export const secondInFutureTimestampMs = (): number => { return new Date(Date.now() + 1000).getTime(); }; + +/** + * Resets a single {@link Scope} to its pristine state. + * + * JS v11 removed `Scope.clear()` — MIGRATION.md advises re-initializing the SDK + * or running code in a fresh scope via `withScope`/`withIsolationScope`, neither + * of which fits the suite's shared `beforeEach` reset of the current, isolation + * and global scopes. This mirrors exactly what the removed `clear()` reset: + * breadcrumbs, tags, attributes, extra, user, contexts, level, transaction name, + * fingerprint, session, conversation id, active span, attachments and the + * propagation context. As in the original, the client and event processors are + * intentionally left intact. Reaching into the `_`-prefixed fields is deliberate + * and confined to test setup. + */ +function resetScope(scope: Scope): void { + const internal = scope as unknown as { + _breadcrumbs: unknown[]; + _tags: Record; + _attributes: Record; + _extra: Record; + _user: Record; + _contexts: Record; + _level: unknown; + _transactionName: unknown; + _fingerprint: unknown; + _session: unknown; + _conversationId: unknown; + _attachments: unknown[]; + }; + + internal._breadcrumbs = []; + internal._tags = {}; + internal._attributes = {}; + internal._extra = {}; + internal._user = {}; + internal._contexts = {}; + internal._level = undefined; + internal._transactionName = undefined; + internal._fingerprint = undefined; + internal._session = undefined; + internal._conversationId = undefined; + internal._attachments = []; + _INTERNAL_setSpanForScope(scope, undefined); + scope.setPropagationContext({ traceId: generateTraceId(), sampleRand: Math.random() }); +} + +/** + * Resets the current, isolation and global Sentry scopes to a pristine state + * between tests. Drop-in replacement for the pre-v11 + * `getCurrentScope().clear(); getIsolationScope().clear(); getGlobalScope().clear();` + * block that the suite relied on before `Scope.clear()` was removed. + */ +export function clearAllScopes(): void { + resetScope(getCurrentScope()); + resetScope(getIsolationScope()); + resetScope(getGlobalScope()); +} diff --git a/packages/core/test/tracing/integrations/appStart.test.ts b/packages/core/test/tracing/integrations/appStart.test.ts index 86b5122344..dfb6711a1a 100644 --- a/packages/core/test/tracing/integrations/appStart.test.ts +++ b/packages/core/test/tracing/integrations/appStart.test.ts @@ -53,7 +53,7 @@ import { RN_GLOBAL_OBJ } from '../../../src/js/utils/worldwide'; import { NATIVE } from '../../../src/js/wrapper'; import { mockAppRegistryIntegration } from '../../mocks/appRegistryIntegrationMock'; import { getDefaultTestClientOptions, TestClient } from '../../mocks/client'; -import { mockFunction } from '../../testutils'; +import { clearAllScopes, mockFunction } from '../../testutils'; type AppStartIntegrationTest = ReturnType & { setFirstStartedActiveRootSpanId: (spanId: string | undefined) => void; @@ -413,9 +413,7 @@ describe('App Start Integration', () => { }); it('Does not add app start span twice', async () => { - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); const [timeOriginMilliseconds, appStartTimeMilliseconds] = mockAppStart({ cold: true }); @@ -467,9 +465,7 @@ describe('App Start Integration', () => { // starts a navigation transaction before the standalone app start transaction is created. // The fix ensures that when standalone: true, the span ID check is skipped so app start // can be attached to the standalone transaction even if a navigation transaction started first. - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); mockAppStart({ cold: true }); @@ -519,9 +515,7 @@ describe('App Start Integration', () => { }); it('Connects the standalone app start transaction to the active trace', async () => { - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); mockAppStart({ cold: true }); @@ -1302,9 +1296,7 @@ describe('Extended App Start', () => { beforeEach(() => { jest.clearAllMocks(); mockReactNativeBundleExecutionStartTimestamp(); - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); _clearAppStartEndData(); _clearRootComponentCreationTimestampMs(); }); @@ -1895,9 +1887,7 @@ describe('appLoaded() standalone mode', () => { }); it('triggers standalone app start capture via appLoaded()', async () => { - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); const [, appStartTimeMilliseconds] = mockAppStart({ cold: true }); @@ -1930,9 +1920,7 @@ describe('appLoaded() standalone mode', () => { }); it('overrides already-flushed standalone transaction when appLoaded() is called after auto-capture', async () => { - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); const [, appStartTimeMilliseconds] = mockAppStart({ cold: true }); @@ -1974,9 +1962,7 @@ describe('appLoaded() standalone mode', () => { it('sends deferred standalone transaction when appLoaded() is not called', async () => { jest.useFakeTimers(); - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); const [, appStartTimeMilliseconds] = mockAppStart({ cold: true }); @@ -2014,9 +2000,7 @@ describe('appLoaded() standalone mode', () => { it('does not send a second standalone transaction when appLoaded() arrives after the deferred auto-capture fired', async () => { jest.useFakeTimers(); - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); mockAppStart({ cold: true }); @@ -2050,9 +2034,7 @@ describe('appLoaded() standalone mode', () => { }); it('does not send a second standalone transaction when appLoaded() races an in-flight capture', async () => { - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); // Reset module-level state so the test is hermetic (clears isAppLoadedManuallyInvoked so // appLoaded() actually runs its capture, and any leaked app start end data). _clearAppStartEndData(); @@ -2104,9 +2086,7 @@ describe('appLoaded() standalone mode', () => { }); it('captures once per run and re-captures for a new run after runApplication', async () => { - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); _clearAppStartEndData(); _clearRootComponentCreationTimestampMs(); @@ -2144,9 +2124,7 @@ describe('appLoaded() standalone mode', () => { }); it('allows auto-capture again after isAppLoadedManuallyInvoked is reset', async () => { - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); mockAppStart({ cold: true }); @@ -2448,9 +2426,7 @@ function expectStandaloneChildrenHaveAppStartVitals( } async function captureStandAloneAppStart(): Promise | Event | null> { - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); const integration = appStartIntegration({ standalone: true, diff --git a/packages/core/test/tracing/integrations/nativeframes.test.ts b/packages/core/test/tracing/integrations/nativeframes.test.ts index 695bca3d2f..f96c7637a5 100644 --- a/packages/core/test/tracing/integrations/nativeframes.test.ts +++ b/packages/core/test/tracing/integrations/nativeframes.test.ts @@ -5,7 +5,7 @@ import { getCurrentScope, getGlobalScope, getIsolationScope, setCurrentClient, s import { nativeFramesIntegration } from '../../../src/js'; import { NATIVE } from '../../../src/js/wrapper'; import { getDefaultTestClientOptions, TestClient } from '../../mocks/client'; -import { mockFunction } from '../../testutils'; +import { clearAllScopes, mockFunction } from '../../testutils'; jest.mock('../../../src/js/wrapper', () => { return { @@ -34,9 +34,7 @@ describe('NativeFramesInstrumentation', () => { beforeEach(() => { global.Date.now = jest.fn(() => mockDate.getTime()); - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); const options = getDefaultTestClientOptions({ tracesSampleRate: 1.0, @@ -469,7 +467,7 @@ describe('NativeFramesInstrumentation', () => { // Start and complete txn-2 during txn-1's event processing. // With a global variable (old code), txn-2's child end would overwrite txn-1's data. // Clear scope so txn-2 is a new root span, not a child of txn-1. - getCurrentScope().clear(); + clearAllScopes(); await startSpan({ name: 'txn-2' }, async () => { startSpan({ name: 'txn-2-child' }, () => {}); await Promise.resolve(); @@ -528,9 +526,7 @@ describe('NativeFramesInstrumentation', () => { beforeEach(() => { global.Date.now = jest.fn(() => mockDate.getTime()); - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); const options = getDefaultTestClientOptions({ tracesSampleRate: 0, diff --git a/packages/core/test/tracing/integrations/stallTracking/stalltracking.test.ts b/packages/core/test/tracing/integrations/stallTracking/stalltracking.test.ts index b4d5dbb43e..e9f1cff55e 100644 --- a/packages/core/test/tracing/integrations/stallTracking/stalltracking.test.ts +++ b/packages/core/test/tracing/integrations/stallTracking/stalltracking.test.ts @@ -14,6 +14,7 @@ import { import { stallTrackingIntegration } from '../../../../src/js/tracing/integrations/stalltracking'; import { getDefaultTestClientOptions, TestClient } from '../../../mocks/client'; import { expectNonZeroStallMeasurements, expectStallMeasurements } from './stalltrackingutils'; +import { clearAllScopes } from '../../../testutils'; jest.useFakeTimers({ advanceTimers: true, @@ -35,9 +36,7 @@ describe('StallTracking', () => { let client: TestClient; beforeEach(() => { - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); const options = getDefaultTestClientOptions({ tracesSampleRate: 1.0, @@ -229,9 +228,7 @@ describe('StallTracking', () => { }); it('does not track stalls for unsampled spans', async () => { - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); const unsampledOptions = getDefaultTestClientOptions({ tracesSampleRate: 0, diff --git a/packages/core/test/tracing/reactnativenavigation.test.ts b/packages/core/test/tracing/reactnativenavigation.test.ts index 1ff880b599..6f0658418c 100644 --- a/packages/core/test/tracing/reactnativenavigation.test.ts +++ b/packages/core/test/tracing/reactnativenavigation.test.ts @@ -35,6 +35,7 @@ import { } from '../../src/js/tracing/semanticAttributes'; import { SPAN_THREAD_NAME, SPAN_THREAD_NAME_JAVASCRIPT } from '../../src/js/tracing/span'; import { getDefaultTestClientOptions, TestClient } from '../mocks/client'; +import { clearAllScopes } from '../testutils'; interface MockEventsRegistry extends EventsRegistry { componentWillAppearListener?: (event: ComponentWillAppearEvent) => void; @@ -55,9 +56,7 @@ describe('React Native Navigation Instrumentation', () => { let client: TestClient; beforeEach(() => { - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); }); test('Correctly instruments a route change', async () => { diff --git a/packages/core/test/tracing/reactnavigation.stalltracking.test.ts b/packages/core/test/tracing/reactnavigation.stalltracking.test.ts index e33da6c377..fabff75618 100644 --- a/packages/core/test/tracing/reactnavigation.stalltracking.test.ts +++ b/packages/core/test/tracing/reactnavigation.stalltracking.test.ts @@ -12,6 +12,7 @@ import { RN_GLOBAL_OBJ } from '../../src/js/utils/worldwide'; import { getDefaultTestClientOptions, TestClient } from '../mocks/client'; import { expectStallMeasurements } from './integrations/stallTracking/stalltrackingutils'; import { createMockNavigationAndAttachTo } from './reactnavigationutils'; +import { clearAllScopes } from '../testutils'; jest.useFakeTimers({ advanceTimers: true, @@ -25,9 +26,7 @@ describe('StallTracking with ReactNavigation', () => { beforeEach(() => { RN_GLOBAL_OBJ.__sentry_rn_v5_registered = false; - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); const rnavigation = reactNavigationIntegration(); mockNavigation = createMockNavigationAndAttachTo(rnavigation); diff --git a/packages/core/test/tracing/reactnavigation.test.ts b/packages/core/test/tracing/reactnavigation.test.ts index c04743968d..2cd19e1642 100644 --- a/packages/core/test/tracing/reactnavigation.test.ts +++ b/packages/core/test/tracing/reactnavigation.test.ts @@ -40,6 +40,7 @@ import { getDefaultTestClientOptions, TestClient } from '../mocks/client'; import { NATIVE } from '../mockWrapper'; import { getDevServer } from './../../src/js/integrations/debugsymbolicatorutils'; import { createMockNavigationAndAttachTo, createMockNavigationWithNestedState } from './reactnavigationutils'; +import { clearAllScopes } from '../testutils'; const dummyRoute = { name: 'Route', @@ -122,9 +123,7 @@ describe('ReactNavigationInstrumentation', () => { jest.clearAllMocks(); RN_GLOBAL_OBJ.__sentry_rn_v5_registered = false; - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); }); test('transaction set on initialize', async () => { diff --git a/packages/core/test/tracing/timetodisplay.test.tsx b/packages/core/test/tracing/timetodisplay.test.tsx index c12521157c..ac4eb459bc 100644 --- a/packages/core/test/tracing/timetodisplay.test.tsx +++ b/packages/core/test/tracing/timetodisplay.test.tsx @@ -42,7 +42,7 @@ import { } from '../../src/js/tracing/timetodisplay'; import { _resetTimeToDisplayCoordinator } from '../../src/js/tracing/timeToDisplayCoordinator'; import { getDefaultTestClientOptions, TestClient } from '../mocks/client'; -import { nowInSeconds, secondAgoTimestampMs, secondInFutureTimestampMs } from '../testutils'; +import { clearAllScopes, nowInSeconds, secondAgoTimestampMs, secondInFutureTimestampMs } from '../testutils'; jest.mock('../../src/js/utils/environment', () => ({ isWeb: jest.fn().mockReturnValue(false), @@ -81,9 +81,7 @@ describe('TimeToDisplay', () => { beforeEach(() => { clearMockedOnDrawReportedProps(); _resetTimeToDisplayCoordinator(); - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); const options = getDefaultTestClientOptions({ tracesSampleRate: 1.0, @@ -534,9 +532,7 @@ describe('Frame Data', () => { beforeEach(() => { clearMockedOnDrawReportedProps(); - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); const options = getDefaultTestClientOptions({ tracesSampleRate: 1.0, @@ -1004,9 +1000,7 @@ describe('reportFullyDisplayed', () => { clearMockedOnDrawReportedProps(); _resetTimeToDisplayCoordinator(); _resetImperativeTtfdTimestamps(); - getCurrentScope().clear(); - getIsolationScope().clear(); - getGlobalScope().clear(); + clearAllScopes(); const options = getDefaultTestClientOptions({ tracesSampleRate: 1.0, diff --git a/samples/expo/package.json b/samples/expo/package.json index dad229c4b3..9effbdba68 100644 --- a/samples/expo/package.json +++ b/samples/expo/package.json @@ -23,7 +23,7 @@ "eas-build-development-android": "eas build --profile development --platform android" }, "dependencies": { - "@sentry/core": "10.73.0", + "@sentry/core": "11.0.0-alpha.2", "@sentry/react-native": "8.24.0", "@types/react": "~19.2.10", "expo": "^57.0.0", @@ -47,7 +47,7 @@ "devDependencies": { "@babel/core": "^7.26.0", "@babel/preset-env": "^7.26.0", - "@sentry/bundler-plugins": "10.73.0", + "@sentry/bundler-plugins": "11.0.0-alpha.2", "@types/node": "20.10.4", "sentry-react-native-samples-utils": "workspace:^" }, diff --git a/samples/react-native-macos/package.json b/samples/react-native-macos/package.json index 39c9300c38..80517ce1d1 100644 --- a/samples/react-native-macos/package.json +++ b/samples/react-native-macos/package.json @@ -16,8 +16,8 @@ "@react-navigation/bottom-tabs": "^6.5.12", "@react-navigation/native": "^6.1.9", "@react-navigation/stack": "^6.3.20", - "@sentry/core": "10.73.0", - "@sentry/react": "10.73.0", + "@sentry/core": "11.0.0-alpha.2", + "@sentry/react": "11.0.0-alpha.2", "@sentry/react-native": "8.24.0", "delay": "^6.0.0", "react": "19.1.4", diff --git a/samples/react-native/package.json b/samples/react-native/package.json index 03f943072d..79d07199d9 100644 --- a/samples/react-native/package.json +++ b/samples/react-native/package.json @@ -48,8 +48,8 @@ "@react-navigation/native-stack": "^7.3.24", "@react-navigation/stack": "^7.4.5", "@reduxjs/toolkit": "^2.8.2", - "@sentry/core": "10.73.0", - "@sentry/react": "10.73.0", + "@sentry/core": "11.0.0-alpha.2", + "@sentry/react": "11.0.0-alpha.2", "@sentry/react-native": "8.24.0", "@shopify/flash-list": "^2.0.2", "delay": "^6.0.0", @@ -79,7 +79,7 @@ "@react-native/jest-preset": "0.87.1", "@react-native/metro-config": "0.87.1", "@react-native/typescript-config": "0.87.1", - "@sentry/bundler-plugins": "10.73.0", + "@sentry/bundler-plugins": "11.0.0-alpha.2", "@testing-library/react-native": "^13.2.2", "@types/jest": "^29.5.14", "@types/node": "^22.13.1", diff --git a/yarn.lock b/yarn.lock index 51c125a2d1..9c109ea328 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9960,41 +9960,43 @@ __metadata: languageName: node linkType: hard -"@sentry/browser-utils@npm:10.73.0": - version: 10.73.0 - resolution: "@sentry/browser-utils@npm:10.73.0" +"@sentry/browser-utils@npm:11.0.0-alpha.2": + version: 11.0.0-alpha.2 + resolution: "@sentry/browser-utils@npm:11.0.0-alpha.2" dependencies: - "@sentry/conventions": "npm:^0.16.0" - "@sentry/core": "npm:10.73.0" - checksum: 10c0/01ce6ee0f8b009560a6a05d073a244152011aea0fbdc4198f16308bace6ef80a0dd9dcf5d0dacc3bf2198da1d346159e67c17060ab6720b28f73e8766c0e784c + "@sentry/conventions": "npm:^0.20.0" + "@sentry/core": "npm:11.0.0-alpha.2" + web-vitals: "npm:^6.0.1" + checksum: 10c0/77a18bf555b1ed7d2fe0473739dce1a64849b5a6e62d356010fde3808fb289f207812f33c85a1233264711cc2b6158d6c11cecfbede5f00c119584b4a32807a6 languageName: node linkType: hard -"@sentry/browser@npm:10.73.0": - version: 10.73.0 - resolution: "@sentry/browser@npm:10.73.0" +"@sentry/browser@npm:11.0.0-alpha.2": + version: 11.0.0-alpha.2 + resolution: "@sentry/browser@npm:11.0.0-alpha.2" dependencies: - "@sentry/browser-utils": "npm:10.73.0" - "@sentry/conventions": "npm:^0.16.0" - "@sentry/core": "npm:10.73.0" - "@sentry/feedback": "npm:10.73.0" - "@sentry/replay": "npm:10.73.0" - "@sentry/replay-canvas": "npm:10.73.0" - checksum: 10c0/5d6f9581ca8c142d6a4c409c9f34c6f3f5585c3006da12e952836ff83b9bf4fd6c0e0f650b245be4d5497ac4bb8f34d7c658a79300ecd2b165db262fd36c3544 + "@sentry/browser-utils": "npm:11.0.0-alpha.2" + "@sentry/conventions": "npm:^0.20.0" + "@sentry/core": "npm:11.0.0-alpha.2" + "@sentry/feedback": "npm:11.0.0-alpha.2" + "@sentry/replay": "npm:11.0.0-alpha.2" + "@sentry/replay-canvas": "npm:11.0.0-alpha.2" + checksum: 10c0/9c276f13e4513fda67a1efa6ac4d4d72abce29b5a79b8a6a08ce5f254f7b63a2e654f01683708437320774e0cd30b608a2ff6bf95dfb1ca42657e753bb7d0d84 languageName: node linkType: hard -"@sentry/bundler-plugins@npm:10.73.0": - version: 10.73.0 - resolution: "@sentry/bundler-plugins@npm:10.73.0" +"@sentry/bundler-plugins@npm:11.0.0-alpha.2": + version: 11.0.0-alpha.2 + resolution: "@sentry/bundler-plugins@npm:11.0.0-alpha.2" dependencies: "@babel/core": "npm:^7.18.5" - "@sentry/cli": "npm:^2.58.6" - "@sentry/core": "npm:10.73.0" + "@sentry/core": "npm:11.0.0-alpha.2" dotenv: "npm:^17.4.2" find-up: "npm:^5.0.0" glob: "npm:^13.0.6" magic-string: "npm:~0.30.8" + sentry: "npm:^0.44.0" + supports-color: "npm:^8.1.1" peerDependencies: rollup: ">=3.2.0" webpack: ">=5.0.0" @@ -10003,14 +10005,7 @@ __metadata: optional: true webpack: optional: true - checksum: 10c0/4dc13135609328978863d885edd3452368bd7da2d35d9ed6c85e8304df34485758ad465b3d6aad528cdd56cafe261c47c315c628e0ba25dffc9082ac3c3a322e - languageName: node - linkType: hard - -"@sentry/cli-darwin@npm:2.58.6": - version: 2.58.6 - resolution: "@sentry/cli-darwin@npm:2.58.6" - conditions: os=darwin + checksum: 10c0/23cc847fdc9c01264ab0bdab022a987b0d6302ccc1a8900617fa9830915eb327725ca4bbe2c6a85f61f223faa10642706d4871d90967f3d168d31503555da126 languageName: node linkType: hard @@ -10021,13 +10016,6 @@ __metadata: languageName: node linkType: hard -"@sentry/cli-linux-arm64@npm:2.58.6": - version: 2.58.6 - resolution: "@sentry/cli-linux-arm64@npm:2.58.6" - conditions: (os=linux | os=freebsd | os=android) & cpu=arm64 - languageName: node - linkType: hard - "@sentry/cli-linux-arm64@npm:3.7.0": version: 3.7.0 resolution: "@sentry/cli-linux-arm64@npm:3.7.0" @@ -10035,13 +10023,6 @@ __metadata: languageName: node linkType: hard -"@sentry/cli-linux-arm@npm:2.58.6": - version: 2.58.6 - resolution: "@sentry/cli-linux-arm@npm:2.58.6" - conditions: (os=linux | os=freebsd | os=android) & cpu=arm - languageName: node - linkType: hard - "@sentry/cli-linux-arm@npm:3.7.0": version: 3.7.0 resolution: "@sentry/cli-linux-arm@npm:3.7.0" @@ -10049,13 +10030,6 @@ __metadata: languageName: node linkType: hard -"@sentry/cli-linux-i686@npm:2.58.6": - version: 2.58.6 - resolution: "@sentry/cli-linux-i686@npm:2.58.6" - conditions: (os=linux | os=freebsd | os=android) & (cpu=x86 | cpu=ia32) - languageName: node - linkType: hard - "@sentry/cli-linux-i686@npm:3.7.0": version: 3.7.0 resolution: "@sentry/cli-linux-i686@npm:3.7.0" @@ -10063,13 +10037,6 @@ __metadata: languageName: node linkType: hard -"@sentry/cli-linux-x64@npm:2.58.6": - version: 2.58.6 - resolution: "@sentry/cli-linux-x64@npm:2.58.6" - conditions: (os=linux | os=freebsd | os=android) & cpu=x64 - languageName: node - linkType: hard - "@sentry/cli-linux-x64@npm:3.7.0": version: 3.7.0 resolution: "@sentry/cli-linux-x64@npm:3.7.0" @@ -10077,13 +10044,6 @@ __metadata: languageName: node linkType: hard -"@sentry/cli-win32-arm64@npm:2.58.6": - version: 2.58.6 - resolution: "@sentry/cli-win32-arm64@npm:2.58.6" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - "@sentry/cli-win32-arm64@npm:3.7.0": version: 3.7.0 resolution: "@sentry/cli-win32-arm64@npm:3.7.0" @@ -10091,13 +10051,6 @@ __metadata: languageName: node linkType: hard -"@sentry/cli-win32-i686@npm:2.58.6": - version: 2.58.6 - resolution: "@sentry/cli-win32-i686@npm:2.58.6" - conditions: os=win32 & (cpu=x86 | cpu=ia32) - languageName: node - linkType: hard - "@sentry/cli-win32-i686@npm:3.7.0": version: 3.7.0 resolution: "@sentry/cli-win32-i686@npm:3.7.0" @@ -10105,13 +10058,6 @@ __metadata: languageName: node linkType: hard -"@sentry/cli-win32-x64@npm:2.58.6": - version: 2.58.6 - resolution: "@sentry/cli-win32-x64@npm:2.58.6" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - "@sentry/cli-win32-x64@npm:3.7.0": version: 3.7.0 resolution: "@sentry/cli-win32-x64@npm:3.7.0" @@ -10158,46 +10104,6 @@ __metadata: languageName: node linkType: hard -"@sentry/cli@npm:^2.58.6": - version: 2.58.6 - resolution: "@sentry/cli@npm:2.58.6" - dependencies: - "@sentry/cli-darwin": "npm:2.58.6" - "@sentry/cli-linux-arm": "npm:2.58.6" - "@sentry/cli-linux-arm64": "npm:2.58.6" - "@sentry/cli-linux-i686": "npm:2.58.6" - "@sentry/cli-linux-x64": "npm:2.58.6" - "@sentry/cli-win32-arm64": "npm:2.58.6" - "@sentry/cli-win32-i686": "npm:2.58.6" - "@sentry/cli-win32-x64": "npm:2.58.6" - https-proxy-agent: "npm:^5.0.0" - node-fetch: "npm:^2.6.7" - progress: "npm:^2.0.3" - proxy-from-env: "npm:^1.1.0" - which: "npm:^2.0.2" - dependenciesMeta: - "@sentry/cli-darwin": - optional: true - "@sentry/cli-linux-arm": - optional: true - "@sentry/cli-linux-arm64": - optional: true - "@sentry/cli-linux-i686": - optional: true - "@sentry/cli-linux-x64": - optional: true - "@sentry/cli-win32-arm64": - optional: true - "@sentry/cli-win32-i686": - optional: true - "@sentry/cli-win32-x64": - optional: true - bin: - sentry-cli: bin/sentry-cli - checksum: 10c0/3037c8c03d0b56114d4bdccc409a88b2e48df3544b2ddd800556a70d45b72e889e1dc5fc1a2997d962f9d047e360d30e5090d8f454078c9d7be1545ad32e7c0c - languageName: node - linkType: hard - "@sentry/conventions@npm:^0.16.0": version: 0.16.0 resolution: "@sentry/conventions@npm:0.16.0" @@ -10205,6 +10111,13 @@ __metadata: languageName: node linkType: hard +"@sentry/conventions@npm:^0.20.0": + version: 0.20.0 + resolution: "@sentry/conventions@npm:0.20.0" + checksum: 10c0/8b294e5a7c64b0e46b3d5056043f31c86c1e295c46045734d9149ad57587824608cb9f01498e6abe4492becab842e73c4eb27285e7c981ac67cd3a354060efaf + languageName: node + linkType: hard + "@sentry/core@npm:10.70.0": version: 10.70.0 resolution: "@sentry/core@npm:10.70.0" @@ -10214,19 +10127,19 @@ __metadata: languageName: node linkType: hard -"@sentry/core@npm:10.73.0": - version: 10.73.0 - resolution: "@sentry/core@npm:10.73.0" +"@sentry/core@npm:11.0.0-alpha.2": + version: 11.0.0-alpha.2 + resolution: "@sentry/core@npm:11.0.0-alpha.2" dependencies: - "@sentry/conventions": "npm:^0.16.0" - checksum: 10c0/553469fd82ec11f5697ab4b2881b6f811834a1036e88afe24920940f131d59ad1dfcd008b99656661c49c7c9de51678719b884b0a6cfcb696312fd58bb911495 + "@sentry/conventions": "npm:^0.20.0" + checksum: 10c0/66284b4486911cd0df3535b6ae95112b0afe852ac3ad1d69c802c3249662db1084050e2c635396792f22b78d96f000a84280ab0d57b10adcd1edb9467debfc5f languageName: node linkType: hard -"@sentry/eslint-plugin-sdk@npm:10.73.0": - version: 10.73.0 - resolution: "@sentry/eslint-plugin-sdk@npm:10.73.0" - checksum: 10c0/2c6ece825d2782e8cfa76e373c9588411e16368116ac99fb70a938f39254e78da00e216a037ff80ddafaf752bc41fa1f95256fe5640d6a0f94c501004b6f7be4 +"@sentry/eslint-plugin-sdk@npm:11.0.0-alpha.2": + version: 11.0.0-alpha.2 + resolution: "@sentry/eslint-plugin-sdk@npm:11.0.0-alpha.2" + checksum: 10c0/0a779134b3436af482462c6bfe9ce642ecb0360fb834bf3f02cec49dfa5a23cfc98ddc3be8152f32aa7087e91752e2050f185645f41dd64736597e102b7ab140 languageName: node linkType: hard @@ -10248,12 +10161,12 @@ __metadata: languageName: unknown linkType: soft -"@sentry/feedback@npm:10.73.0": - version: 10.73.0 - resolution: "@sentry/feedback@npm:10.73.0" +"@sentry/feedback@npm:11.0.0-alpha.2": + version: 11.0.0-alpha.2 + resolution: "@sentry/feedback@npm:11.0.0-alpha.2" dependencies: - "@sentry/core": "npm:10.73.0" - checksum: 10c0/7dcb318f742a9d4aa5379be889df6f55fab9e5dcbaed0a0a1c90565f8ea6047c562435616c5bbe5a78bdb3a31dc3d023b16ff082c6c8c908aaec8255da801112 + "@sentry/core": "npm:11.0.0-alpha.2" + checksum: 10c0/746ffc4a5e906d3d4594c440ac16ca4857a615661950955ea55b004a05eb08433c2356e939ee48b1fa2daf16a45c799b74727f33c6b4d3a6a9033f6771a5b9a7 languageName: node linkType: hard @@ -10327,14 +10240,14 @@ __metadata: "@mswjs/interceptors": "npm:^0.25.15" "@react-native/babel-preset": "npm:0.87.1" "@react-native/jest-preset": "npm:0.87.1" - "@sentry/browser": "npm:10.73.0" - "@sentry/bundler-plugins": "npm:10.73.0" + "@sentry/browser": "npm:11.0.0-alpha.2" + "@sentry/bundler-plugins": "npm:11.0.0-alpha.2" "@sentry/cli": "npm:3.7.0" - "@sentry/core": "npm:10.73.0" - "@sentry/eslint-plugin-sdk": "npm:10.73.0" + "@sentry/core": "npm:11.0.0-alpha.2" + "@sentry/eslint-plugin-sdk": "npm:11.0.0-alpha.2" "@sentry/expo-upload-sourcemaps": "workspace:*" - "@sentry/react": "npm:10.73.0" - "@sentry/typescript": "npm:10.73.0" + "@sentry/react": "npm:11.0.0-alpha.2" + "@sentry/typescript": "npm:11.0.0-alpha.2" "@sentry/wizard": "npm:7.0.3" "@testing-library/react-native": "npm:^13.2.2" "@types/jest": "npm:^29.5.13" @@ -10380,36 +10293,36 @@ __metadata: languageName: unknown linkType: soft -"@sentry/react@npm:10.73.0": - version: 10.73.0 - resolution: "@sentry/react@npm:10.73.0" +"@sentry/react@npm:11.0.0-alpha.2": + version: 11.0.0-alpha.2 + resolution: "@sentry/react@npm:11.0.0-alpha.2" dependencies: - "@sentry/browser": "npm:10.73.0" - "@sentry/conventions": "npm:^0.16.0" - "@sentry/core": "npm:10.73.0" + "@sentry/browser": "npm:11.0.0-alpha.2" + "@sentry/conventions": "npm:^0.20.0" + "@sentry/core": "npm:11.0.0-alpha.2" peerDependencies: - react: ^16.14.0 || 17.x || 18.x || 19.x - checksum: 10c0/84afea9290b8a59486566abc011dfee353c0427cf9a22725444a762153a10c31d61eb7b2e5c8cc458bf245e9974b9a2993dadf066e976e5c429bf324559ecefc + react: 17.x || 18.x || 19.x + checksum: 10c0/40ccc19d70258bd98f5a75cffcffd6e835db24bc101e59545dcd70b4f68f9f59c8eeab1c393a0092ade95d901454a8293698252bb1aab37506776f7e360b1096 languageName: node linkType: hard -"@sentry/replay-canvas@npm:10.73.0": - version: 10.73.0 - resolution: "@sentry/replay-canvas@npm:10.73.0" +"@sentry/replay-canvas@npm:11.0.0-alpha.2": + version: 11.0.0-alpha.2 + resolution: "@sentry/replay-canvas@npm:11.0.0-alpha.2" dependencies: - "@sentry/core": "npm:10.73.0" - "@sentry/replay": "npm:10.73.0" - checksum: 10c0/1ba25555afaa65bfc731a2b997a73a24c0f502ef15514dca9e068bb44acb3538fafe317c6e7fb3fe58df9a6f1a7915245f61dd4ab1ee6e4ef2bb713280e2fe58 + "@sentry/core": "npm:11.0.0-alpha.2" + "@sentry/replay": "npm:11.0.0-alpha.2" + checksum: 10c0/3977261aaf81d7b8e37b68f413b50130f30308fe011edd14423a0d7a6ea8d4dc2da909a2f7eb910e94355feb58273401c565c014f02dcd90e220a9834c87ce77 languageName: node linkType: hard -"@sentry/replay@npm:10.73.0": - version: 10.73.0 - resolution: "@sentry/replay@npm:10.73.0" +"@sentry/replay@npm:11.0.0-alpha.2": + version: 11.0.0-alpha.2 + resolution: "@sentry/replay@npm:11.0.0-alpha.2" dependencies: - "@sentry/browser-utils": "npm:10.73.0" - "@sentry/core": "npm:10.73.0" - checksum: 10c0/f0bfaa9d824afd2abc91d594b24c75d4509908c16761bb6a62e5aeb70c0a3665b40b07e75d4bfdebaa735a4fc29057783fd7465b08b22744221ca7a3d5913ca1 + "@sentry/browser-utils": "npm:11.0.0-alpha.2" + "@sentry/core": "npm:11.0.0-alpha.2" + checksum: 10c0/2d17f132bf984b2d27d9a24c8d0f000c2d5cadedb062b1191cc38a78ee26a6d5c42194d15cf22c76ae95bbbc496722a2a0f4406e4b99347f177f531856f38972 languageName: node linkType: hard @@ -10426,12 +10339,12 @@ __metadata: languageName: node linkType: hard -"@sentry/typescript@npm:10.73.0": - version: 10.73.0 - resolution: "@sentry/typescript@npm:10.73.0" +"@sentry/typescript@npm:11.0.0-alpha.2": + version: 11.0.0-alpha.2 + resolution: "@sentry/typescript@npm:11.0.0-alpha.2" peerDependencies: typescript: ~5.8.0 - checksum: 10c0/6b15c4c7e04d7e474a065c57c3ff1c04884d7cd0a04f9f464f6b4fdcf2a58132cca19157c03f7940b76b0790497fa192bbdcaf862cda812f8c3ecab234877b9b + checksum: 10c0/e63caf3ca01c1c7c729c600e9ca5ca43db04565fe523545e5ad03c339399604599d85201ae6f56e4fdc706c84bd4c71d30d02114eeb3a16d8adc2d07a75cdc9a languageName: node linkType: hard @@ -18971,7 +18884,7 @@ __metadata: languageName: node linkType: hard -"https-proxy-agent@npm:^5.0.0, https-proxy-agent@npm:^5.0.1": +"https-proxy-agent@npm:^5.0.1": version: 5.0.1 resolution: "https-proxy-agent@npm:5.0.1" dependencies: @@ -23990,7 +23903,7 @@ __metadata: languageName: node linkType: hard -"node-fetch@npm:^2.6.12, node-fetch@npm:^2.6.6, node-fetch@npm:^2.6.7": +"node-fetch@npm:^2.6.12, node-fetch@npm:^2.6.6": version: 2.7.0 resolution: "node-fetch@npm:2.7.0" dependencies: @@ -28427,7 +28340,7 @@ __metadata: dependencies: "@babel/preset-env": "npm:^7.25.3" "@babel/preset-typescript": "npm:^7.18.6" - "@sentry/core": "npm:10.73.0" + "@sentry/core": "npm:11.0.0-alpha.2" "@sentry/react-native": "npm:8.24.0" "@types/node": "npm:^20.9.3" "@types/react": "npm:^19.1.4" @@ -28456,8 +28369,8 @@ __metadata: dependencies: "@babel/core": "npm:^7.26.0" "@babel/preset-env": "npm:^7.26.0" - "@sentry/bundler-plugins": "npm:10.73.0" - "@sentry/core": "npm:10.73.0" + "@sentry/bundler-plugins": "npm:11.0.0-alpha.2" + "@sentry/core": "npm:11.0.0-alpha.2" "@sentry/react-native": "npm:8.24.0" "@types/node": "npm:20.10.4" "@types/react": "npm:~19.2.10" @@ -28498,8 +28411,8 @@ __metadata: "@react-navigation/bottom-tabs": "npm:^6.5.12" "@react-navigation/native": "npm:^6.1.9" "@react-navigation/stack": "npm:^6.3.20" - "@sentry/core": "npm:10.73.0" - "@sentry/react": "npm:10.73.0" + "@sentry/core": "npm:11.0.0-alpha.2" + "@sentry/react": "npm:11.0.0-alpha.2" "@sentry/react-native": "npm:8.24.0" "@types/react": "npm:^19.1.4" "@types/react-native-vector-icons": "npm:^6.4.18" @@ -28544,9 +28457,9 @@ __metadata: "@react-navigation/native-stack": "npm:^7.3.24" "@react-navigation/stack": "npm:^7.4.5" "@reduxjs/toolkit": "npm:^2.8.2" - "@sentry/bundler-plugins": "npm:10.73.0" - "@sentry/core": "npm:10.73.0" - "@sentry/react": "npm:10.73.0" + "@sentry/bundler-plugins": "npm:11.0.0-alpha.2" + "@sentry/core": "npm:11.0.0-alpha.2" + "@sentry/react": "npm:11.0.0-alpha.2" "@sentry/react-native": "npm:8.24.0" "@shopify/flash-list": "npm:^2.0.2" "@testing-library/react-native": "npm:^13.2.2" @@ -28613,6 +28526,15 @@ __metadata: languageName: unknown linkType: soft +"sentry@npm:^0.44.0": + version: 0.44.1 + resolution: "sentry@npm:0.44.1" + bin: + sentry: dist/bin.cjs + checksum: 10c0/9fcbaf3761c0229460a48747f2ca744e1451462e59773e9fef21aa7bc394a3b8336fb490b5ff0873084bbd0c93019eb4c86a8c00412781359c370d4cb341e9a6 + languageName: node + linkType: hard + "serialize-error@npm:^11.0.1": version: 11.0.3 resolution: "serialize-error@npm:11.0.3" @@ -29831,7 +29753,7 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^8.0.0, supports-color@npm:~8.1.1": +"supports-color@npm:^8.0.0, supports-color@npm:^8.1.1, supports-color@npm:~8.1.1": version: 8.1.1 resolution: "supports-color@npm:8.1.1" dependencies: @@ -31303,6 +31225,13 @@ __metadata: languageName: node linkType: hard +"web-vitals@npm:^6.0.1": + version: 6.2.1 + resolution: "web-vitals@npm:6.2.1" + checksum: 10c0/6f5cfb5875f6164898ea1097067a8ab29ed6fbd9ad38ac7ea519c110bf1d38a441a5b1e38d18f3afd17c62f9aaa88b6bac3b719bd8e29660f6d939bc12640508 + languageName: node + linkType: hard + "webdriver@npm:8.40.3": version: 8.40.3 resolution: "webdriver@npm:8.40.3" From 5acaf853dd0b37a35932612c489e4add7b59fdc2 Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Wed, 2 Sep 2026 17:25:32 +0200 Subject: [PATCH 2/3] chore(deps): fix lint and API report after v11 alpha.2 bump - Remove orphaned getCurrentScope/getGlobalScope/getIsolationScope imports left by the Scope.clear() -> clearAllScopes() test migration (10 files). - Regenerate the API report to reflect the removed AI instrumentation re-exports and the inboundFilters -> eventFilters rename. Co-Authored-By: Claude Opus 4.8 --- packages/core/etc/sentry-react-native.api.md | 70 +------------------ .../test/integrations/expocontext.test.ts | 2 +- .../expoupdateslistener.integration.test.ts | 1 - .../integrations/expoupdateslistener.test.ts | 3 - .../turboModuleContext.spans.test.ts | 3 - .../tracing/integrations/nativeframes.test.ts | 2 +- .../stallTracking/stalltracking.test.ts | 3 - .../tracing/reactnativenavigation.test.ts | 3 - .../reactnavigation.stalltracking.test.ts | 2 +- .../core/test/tracing/reactnavigation.test.ts | 3 - .../core/test/tracing/timetodisplay.test.tsx | 3 - 11 files changed, 5 insertions(+), 90 deletions(-) diff --git a/packages/core/etc/sentry-react-native.api.md b/packages/core/etc/sentry-react-native.api.md index 55de3c98ae..b12f5c7f5e 100644 --- a/packages/core/etc/sentry-react-native.api.md +++ b/packages/core/etc/sentry-react-native.api.md @@ -8,10 +8,6 @@ import { addBreadcrumb } from '@sentry/core'; import { addConsoleInstrumentationFilter } from '@sentry/core'; import { addEventProcessor } from '@sentry/core'; import { addIntegration } from '@sentry/core'; -import { AnthropicAiClient } from '@sentry/core'; -import { AnthropicAiInstrumentedMethod } from '@sentry/core'; -import { AnthropicAiOptions } from '@sentry/core'; -import { AnthropicAiResponse } from '@sentry/core'; import { Breadcrumb } from '@sentry/core'; import { browserApiErrorsIntegration } from '@sentry/react'; import { globalHandlersIntegration as browserGlobalHandlersIntegration } from '@sentry/react'; @@ -24,10 +20,8 @@ import { captureFeedback } from '@sentry/core'; import { captureMessage } from '@sentry/core'; import { Client } from '@sentry/core'; import type { ClientOptions } from '@sentry/core'; -import { CompiledGraph } from '@sentry/core'; import { consoleLoggingIntegration } from '@sentry/browser'; import { consoleSandbox } from '@sentry/core'; -import { createLangChainCallbackHandler } from '@sentry/core'; import { createReduxEnhancer } from '@sentry/react'; import { dedupeIntegration } from '@sentry/react'; import type { Envelope } from '@sentry/core'; @@ -47,33 +41,17 @@ import { getCurrentScope } from '@sentry/core'; import { getGlobalScope } from '@sentry/core'; import { getIsolationScope } from '@sentry/core'; import { getRootSpan } from '@sentry/core'; -import { GoogleGenAIChat } from '@sentry/core'; -import { GoogleGenAIClient } from '@sentry/core'; -import { GoogleGenAIOptions } from '@sentry/core'; import type { HostComponent } from 'react-native'; import { httpClientIntegration } from '@sentry/react'; import { httpContextIntegration } from '@sentry/react'; import type { ImageStyle } from 'react-native'; -import { inboundFiltersIntegration } from '@sentry/react'; -import { instrumentAnthropicAiClient } from '@sentry/core'; -import { InstrumentedMethod } from '@sentry/core'; -import { instrumentGoogleGenAIClient } from '@sentry/core'; -import { instrumentLangGraph } from '@sentry/core'; -import { instrumentOpenAiClient } from '@sentry/core'; -import { instrumentStateGraph } from '@sentry/core'; -import { instrumentStateGraphCompile } from '@sentry/core'; +import { eventFiltersIntegration as inboundFiltersIntegration } from '@sentry/react'; import { Integration } from '@sentry/core'; -import { LangChainIntegration } from '@sentry/core'; -import { LangChainOptions } from '@sentry/core'; -import { LangGraphIntegration } from '@sentry/core'; -import { LangGraphOptions } from '@sentry/core'; import { lastEventId } from '@sentry/core'; import { logger } from '@sentry/browser'; import type { makeFetchTransport } from '@sentry/browser'; import { Metric } from '@sentry/core'; import { metrics } from '@sentry/browser'; -import { OpenAiClient } from '@sentry/core'; -import { OpenAiOptions } from '@sentry/core'; import type { Options } from '@sentry/core'; import { Profiler } from '@sentry/react'; import * as React_2 from 'react'; @@ -126,14 +104,6 @@ export { addEventProcessor } export { addIntegration } -export { AnthropicAiClient } - -export { AnthropicAiInstrumentedMethod } - -export { AnthropicAiOptions } - -export { AnthropicAiResponse } - // @public export function appLoaded(): void; @@ -179,8 +149,6 @@ export { captureMessage } // @public export function close(): Promise; -export { CompiledGraph } - export { consoleLoggingIntegration } export { consoleSandbox } @@ -188,8 +156,6 @@ export { consoleSandbox } // @public export function crashedLastRun(): Promise; -export { createLangChainCallbackHandler } - // @public (undocumented) export const createNativeFramesIntegrations: (enable: boolean | undefined) => Integration | undefined; @@ -430,12 +396,6 @@ export type GlobalErrorBoundaryProps = ErrorBoundaryProps & { includeUnhandledRejections?: boolean; }; -export { GoogleGenAIChat } - -export { GoogleGenAIClient } - -export { GoogleGenAIOptions } - // Warning: (ae-forgotten-export) The symbol "GraphQLReactNativeIntegrationOptions" needs to be exported by the entry point index.d.ts // // @public @@ -458,28 +418,6 @@ export { inboundFiltersIntegration } // @public export function init(passedOptions: ReactNativeOptions): void; -export { instrumentAnthropicAiClient } - -export { InstrumentedMethod } - -export { instrumentGoogleGenAIClient } - -export { instrumentLangGraph } - -export { instrumentOpenAiClient } - -export { instrumentStateGraph } - -export { instrumentStateGraphCompile } - -export { LangChainIntegration } - -export { LangChainOptions } - -export { LangGraphIntegration } - -export { LangGraphOptions } - export { lastEventId } // @public (undocumented) @@ -552,10 +490,6 @@ export interface NavigationTheme { }; } -export { OpenAiClient } - -export { OpenAiOptions } - // @public export function pauseAppHangTracking(): void; @@ -949,7 +883,7 @@ export function wrapTurboModule(name: string, module: T | null // src/js/feedback/integration.ts:21:5 - (ae-forgotten-export) The symbol "ScreenshotButtonProps" needs to be exported by the entry point index.d.ts // src/js/feedback/integration.ts:23:5 - (ae-forgotten-export) The symbol "FeedbackFormTheme" needs to be exported by the entry point index.d.ts // src/js/tracing/reactnativetracing.ts:90:3 - (ae-forgotten-export) The symbol "ReactNativeTracingState" needs to be exported by the entry point index.d.ts -// src/js/tracing/reactnavigation.ts:228:3 - (ae-forgotten-export) The symbol "RouteOverrideProvider" needs to be exported by the entry point index.d.ts +// src/js/tracing/reactnavigation.ts:230:3 - (ae-forgotten-export) The symbol "RouteOverrideProvider" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) diff --git a/packages/core/test/integrations/expocontext.test.ts b/packages/core/test/integrations/expocontext.test.ts index a9be538f8c..7610d6dc98 100644 --- a/packages/core/test/integrations/expocontext.test.ts +++ b/packages/core/test/integrations/expocontext.test.ts @@ -1,4 +1,4 @@ -import { type Client, type Event, getCurrentScope, getGlobalScope, getIsolationScope } from '@sentry/core'; +import { type Client, type Event } from '@sentry/core'; import type { ExpoUpdates } from '../../src/js/utils/expoglobalobject'; diff --git a/packages/core/test/integrations/expoupdateslistener.integration.test.ts b/packages/core/test/integrations/expoupdateslistener.integration.test.ts index ce2d75c57b..375d31d3fa 100644 --- a/packages/core/test/integrations/expoupdateslistener.integration.test.ts +++ b/packages/core/test/integrations/expoupdateslistener.integration.test.ts @@ -1,6 +1,5 @@ import type { TransactionEvent } from '@sentry/core'; -import { getCurrentScope, getGlobalScope, getIsolationScope } from '@sentry/core'; import { handleSpanLifecycle } from '../../src/js/integrations/expoupdateslistener'; import { SPAN_ORIGIN_AUTO_EXPO_UPDATES } from '../../src/js/tracing/origin'; diff --git a/packages/core/test/integrations/expoupdateslistener.test.ts b/packages/core/test/integrations/expoupdateslistener.test.ts index 555c4d88c0..5066bdb9b8 100644 --- a/packages/core/test/integrations/expoupdateslistener.test.ts +++ b/packages/core/test/integrations/expoupdateslistener.test.ts @@ -1,8 +1,5 @@ import { addBreadcrumb, - getCurrentScope, - getGlobalScope, - getIsolationScope, type Span, SPAN_STATUS_ERROR, SPAN_STATUS_OK, diff --git a/packages/core/test/integrations/turboModuleContext.spans.test.ts b/packages/core/test/integrations/turboModuleContext.spans.test.ts index 1e38e04dbf..28023ca43d 100644 --- a/packages/core/test/integrations/turboModuleContext.spans.test.ts +++ b/packages/core/test/integrations/turboModuleContext.spans.test.ts @@ -15,9 +15,6 @@ import type { Event, Span, TransactionEvent } from '@sentry/core'; import { - getCurrentScope, - getGlobalScope, - getIsolationScope, setCurrentClient, spanToJSON, startNewTrace, diff --git a/packages/core/test/tracing/integrations/nativeframes.test.ts b/packages/core/test/tracing/integrations/nativeframes.test.ts index f96c7637a5..bc35883a58 100644 --- a/packages/core/test/tracing/integrations/nativeframes.test.ts +++ b/packages/core/test/tracing/integrations/nativeframes.test.ts @@ -1,6 +1,6 @@ import type { Event, Measurements } from '@sentry/core'; -import { getCurrentScope, getGlobalScope, getIsolationScope, setCurrentClient, startSpan } from '@sentry/core'; +import { setCurrentClient, startSpan } from '@sentry/core'; import { nativeFramesIntegration } from '../../../src/js'; import { NATIVE } from '../../../src/js/wrapper'; diff --git a/packages/core/test/tracing/integrations/stallTracking/stalltracking.test.ts b/packages/core/test/tracing/integrations/stallTracking/stalltracking.test.ts index e9f1cff55e..06dd42a67e 100644 --- a/packages/core/test/tracing/integrations/stallTracking/stalltracking.test.ts +++ b/packages/core/test/tracing/integrations/stallTracking/stalltracking.test.ts @@ -1,9 +1,6 @@ import type { Span } from '@sentry/core'; import { - getCurrentScope, - getGlobalScope, - getIsolationScope, setCurrentClient, startIdleSpan, startSpan, diff --git a/packages/core/test/tracing/reactnativenavigation.test.ts b/packages/core/test/tracing/reactnativenavigation.test.ts index 6f0658418c..ad2e0fbe03 100644 --- a/packages/core/test/tracing/reactnativenavigation.test.ts +++ b/packages/core/test/tracing/reactnativenavigation.test.ts @@ -3,9 +3,6 @@ import type { EmitterSubscription } from 'react-native'; import { getActiveSpan, - getCurrentScope, - getGlobalScope, - getIsolationScope, setCurrentClient, spanToJSON, } from '@sentry/core'; diff --git a/packages/core/test/tracing/reactnavigation.stalltracking.test.ts b/packages/core/test/tracing/reactnavigation.stalltracking.test.ts index fabff75618..00ace05a9f 100644 --- a/packages/core/test/tracing/reactnavigation.stalltracking.test.ts +++ b/packages/core/test/tracing/reactnavigation.stalltracking.test.ts @@ -3,7 +3,7 @@ jest.mock('../../src/js/tracing/utils', () => ({ isNearToNow: jest.fn(), })); -import { getCurrentScope, getGlobalScope, getIsolationScope, setCurrentClient, startSpanManual } from '@sentry/core'; +import { setCurrentClient, startSpanManual } from '@sentry/core'; import { reactNativeTracingIntegration, reactNavigationIntegration } from '../../src/js'; import { stallTrackingIntegration } from '../../src/js/tracing/integrations/stalltracking'; diff --git a/packages/core/test/tracing/reactnavigation.test.ts b/packages/core/test/tracing/reactnavigation.test.ts index 2cd19e1642..b0e07daab3 100644 --- a/packages/core/test/tracing/reactnavigation.test.ts +++ b/packages/core/test/tracing/reactnavigation.test.ts @@ -3,9 +3,6 @@ import type { Event, Measurements, SentrySpan, StartSpanOptions } from '@sentry/ import * as core from '@sentry/core'; import { getActiveSpan, - getCurrentScope, - getGlobalScope, - getIsolationScope, setCurrentClient, spanToJSON, } from '@sentry/core'; diff --git a/packages/core/test/tracing/timetodisplay.test.tsx b/packages/core/test/tracing/timetodisplay.test.tsx index ac4eb459bc..8440c00078 100644 --- a/packages/core/test/tracing/timetodisplay.test.tsx +++ b/packages/core/test/tracing/timetodisplay.test.tsx @@ -2,9 +2,6 @@ import type { Event, Measurements, Span, SpanJSON } from '@sentry/core'; import { debug, - getCurrentScope, - getGlobalScope, - getIsolationScope, setCurrentClient, spanToJSON, startSpan, From 4bfae4cb3449c62ce6212cbda09734023792f5a1 Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Wed, 2 Sep 2026 17:37:01 +0200 Subject: [PATCH 3/3] style(core): apply oxfmt to v11 alpha.2 migration changes Format the 16 source/test files touched by the v11 migration. The earlier Lint run never reached the oxfmt step because oxlint failed first on the orphaned scope imports; with those fixed, oxfmt --check surfaced the drift. Co-Authored-By: Claude Opus 4.8 --- packages/core/src/js/integrations/deeplink.ts | 2 +- packages/core/src/js/tracing/expoRouter.ts | 3 ++- .../core/src/js/tracing/expoRouterErrorBoundary.tsx | 3 ++- packages/core/src/js/tracing/onSpanEndUtils.ts | 4 +++- packages/core/src/js/tracing/reactnavigation.ts | 6 ++---- packages/core/src/js/tracing/span.ts | 4 +++- packages/core/src/js/tracing/timetodisplay.tsx | 11 ++++++++--- .../expoupdateslistener.integration.test.ts | 1 - .../test/integrations/expoupdateslistener.test.ts | 8 +------- .../integrations/turboModuleContext.spans.test.ts | 7 +------ packages/core/test/mocks/client.ts | 1 + .../integrations/stallTracking/stalltracking.test.ts | 10 ++-------- .../core/test/tracing/reactnativenavigation.test.ts | 6 +----- .../tracing/reactnavigation.stalltracking.test.ts | 2 +- packages/core/test/tracing/reactnavigation.test.ts | 8 ++------ packages/core/test/tracing/timetodisplay.test.tsx | 8 +------- 16 files changed, 31 insertions(+), 53 deletions(-) diff --git a/packages/core/src/js/integrations/deeplink.ts b/packages/core/src/js/integrations/deeplink.ts index 4b7a665926..5196c7f4f2 100644 --- a/packages/core/src/js/integrations/deeplink.ts +++ b/packages/core/src/js/integrations/deeplink.ts @@ -2,11 +2,11 @@ import type { IntegrationFn } from '@sentry/core'; import { addBreadcrumb, defineIntegration, getClient } from '@sentry/core'; +import type { ReactNativeClientOptions } from '../options'; import type { DeepLinkSource } from '../tracing/pendingDeepLink'; import { setPendingDeepLink } from '../tracing/pendingDeepLink'; import { sanitizeUrl } from '../tracing/utils'; -import type { ReactNativeClientOptions } from '../options'; export const INTEGRATION_NAME = 'DeepLink'; diff --git a/packages/core/src/js/tracing/expoRouter.ts b/packages/core/src/js/tracing/expoRouter.ts index 5b7646ea4f..122ad64cf7 100644 --- a/packages/core/src/js/tracing/expoRouter.ts +++ b/packages/core/src/js/tracing/expoRouter.ts @@ -1,8 +1,9 @@ import { addBreadcrumb, getClient, SPAN_STATUS_ERROR, SPAN_STATUS_OK, startInactiveSpan } from '@sentry/core'; +import type { ReactNativeClientOptions } from '../options'; + import { SPAN_ORIGIN_AUTO_EXPO_ROUTER_NAVIGATION, SPAN_ORIGIN_AUTO_EXPO_ROUTER_PREFETCH } from './origin'; import { clearPendingExpoRouterNavigation, setPendingExpoRouterNavigation } from './pendingExpoRouterNavigation'; -import type { ReactNativeClientOptions } from '../options'; type ExpoRouterHref = string | { pathname?: string; params?: Record }; diff --git a/packages/core/src/js/tracing/expoRouterErrorBoundary.tsx b/packages/core/src/js/tracing/expoRouterErrorBoundary.tsx index 9631667d01..a679da4120 100644 --- a/packages/core/src/js/tracing/expoRouterErrorBoundary.tsx +++ b/packages/core/src/js/tracing/expoRouterErrorBoundary.tsx @@ -13,9 +13,10 @@ import { } from '@sentry/core'; import * as React from 'react'; +import type { ReactNativeClientOptions } from '../options'; + import { registerFeatureMarker } from '../utils/featureMarkers'; import { getCurrentExpoRouterRouteInfo } from './expoRouterStore'; -import type { ReactNativeClientOptions } from '../options'; export const EXPO_ROUTER_ERROR_BOUNDARY_INTEGRATION_NAME = 'ExpoRouterErrorBoundary'; diff --git a/packages/core/src/js/tracing/onSpanEndUtils.ts b/packages/core/src/js/tracing/onSpanEndUtils.ts index 601718b568..f8f7ef7dc0 100644 --- a/packages/core/src/js/tracing/onSpanEndUtils.ts +++ b/packages/core/src/js/tracing/onSpanEndUtils.ts @@ -256,7 +256,9 @@ export const cancelInBackground = (client: Client, span: Span): void => { clearTimeout(inactiveTimeout); inactiveTimeout = undefined; } - debug.log(`Setting ${spanToStaticSpanJSON(span).op} transaction to cancelled because the app is in the background.`); + debug.log( + `Setting ${spanToStaticSpanJSON(span).op} transaction to cancelled because the app is in the background.`, + ); // End still-recording http.client children at the time the app left // the foreground, not when the deferred timer fires. On iOS, the JS diff --git a/packages/core/src/js/tracing/reactnavigation.ts b/packages/core/src/js/tracing/reactnavigation.ts index 87c41e2b75..8b4fef0728 100644 --- a/packages/core/src/js/tracing/reactnavigation.ts +++ b/packages/core/src/js/tracing/reactnavigation.ts @@ -14,6 +14,7 @@ import { timestampInSeconds, } from '@sentry/core'; +import type { ReactNativeClientOptions } from '../options'; import type { UnsafeAction } from '../vendor/react-navigation/types'; import type { PendingDeepLink } from './pendingDeepLink'; import type { ReactNativeTracingIntegration } from './reactnativetracing'; @@ -46,8 +47,6 @@ import { } from './span'; import { addTimeToInitialDisplayFallback } from './timeToDisplayFallback'; -import type { ReactNativeClientOptions } from '../options'; - export const INTEGRATION_NAME = 'ReactNavigation'; const NAVIGATION_HISTORY_MAX_SIZE = 200; @@ -947,8 +946,7 @@ function tagSpanWithDeepLink(span: Span, link: PendingDeepLink): boolean { } taggedDeepLinkSpans.add(span); - const sendDefaultPii = - (getClient()?.getOptions() as ReactNativeClientOptions | undefined)?.sendDefaultPii ?? false; + const sendDefaultPii = (getClient()?.getOptions() as ReactNativeClientOptions | undefined)?.sendDefaultPii ?? false; const url = sendDefaultPii ? link.url : sanitizeDeepLinkUrl(link.url); span.setAttributes({ diff --git a/packages/core/src/js/tracing/span.ts b/packages/core/src/js/tracing/span.ts index 0704815cf3..40332fa4dd 100644 --- a/packages/core/src/js/tracing/span.ts +++ b/packages/core/src/js/tracing/span.ts @@ -150,7 +150,9 @@ export function getDefaultIdleNavigationSpanOptions(): StartSpanOptions { * Checks if the span is a Sentry User Interaction span. */ export function isSentryInteractionSpan(span: Span): boolean { - return [SPAN_ORIGIN_AUTO_INTERACTION, SPAN_ORIGIN_MANUAL_INTERACTION].includes(spanToStaticSpanJSON(span).origin || ''); + return [SPAN_ORIGIN_AUTO_INTERACTION, SPAN_ORIGIN_MANUAL_INTERACTION].includes( + spanToStaticSpanJSON(span).origin || '', + ); } export const SCOPE_SPAN_FIELD = '_sentrySpan'; diff --git a/packages/core/src/js/tracing/timetodisplay.tsx b/packages/core/src/js/tracing/timetodisplay.tsx index 3feb934684..90544b4a17 100644 --- a/packages/core/src/js/tracing/timetodisplay.tsx +++ b/packages/core/src/js/tracing/timetodisplay.tsx @@ -226,7 +226,9 @@ export function startTimeToInitialDisplaySpan( return undefined; } - const existingSpan = getSpanDescendants(activeSpan).find(span => spanToStaticSpanJSON(span).op === 'ui.load.initial_display'); + const existingSpan = getSpanDescendants(activeSpan).find( + span => spanToStaticSpanJSON(span).op === 'ui.load.initial_display', + ); if (existingSpan) { debug.log('[TimeToDisplay] Found existing ui.load.initial_display span.'); return existingSpan; @@ -391,7 +393,9 @@ export function updateInitialDisplaySpan( .then(() => { span.end(frameTimestampSeconds); span.setStatus({ code: SPAN_STATUS_OK }); - debug.log(`[TimeToDisplay] ${spanToStaticSpanJSON(span).description} span updated with end timestamp and frame data.`); + debug.log( + `[TimeToDisplay] ${spanToStaticSpanJSON(span).description} span updated with end timestamp and frame data.`, + ); if (fullDisplayBeforeInitialDisplay.has(activeSpan)) { fullDisplayBeforeInitialDisplay.delete(activeSpan); @@ -477,7 +481,8 @@ function updateFullDisplaySpan(frameTimestampSeconds: number, passedInitialDispl const existingInitialDisplaySpan = passedInitialDisplaySpan || getSpanDescendants(activeSpan).find(span => spanToStaticSpanJSON(span).op === 'ui.load.initial_display'); - const initialDisplayEndTimestamp = existingInitialDisplaySpan && spanToStaticSpanJSON(existingInitialDisplaySpan).timestamp; + const initialDisplayEndTimestamp = + existingInitialDisplaySpan && spanToStaticSpanJSON(existingInitialDisplaySpan).timestamp; if (!initialDisplayEndTimestamp) { fullDisplayBeforeInitialDisplay.set(activeSpan, true); debug.warn( diff --git a/packages/core/test/integrations/expoupdateslistener.integration.test.ts b/packages/core/test/integrations/expoupdateslistener.integration.test.ts index 375d31d3fa..05822194e6 100644 --- a/packages/core/test/integrations/expoupdateslistener.integration.test.ts +++ b/packages/core/test/integrations/expoupdateslistener.integration.test.ts @@ -1,6 +1,5 @@ import type { TransactionEvent } from '@sentry/core'; - import { handleSpanLifecycle } from '../../src/js/integrations/expoupdateslistener'; import { SPAN_ORIGIN_AUTO_EXPO_UPDATES } from '../../src/js/tracing/origin'; import { setupTestClient } from '../mocks/client'; diff --git a/packages/core/test/integrations/expoupdateslistener.test.ts b/packages/core/test/integrations/expoupdateslistener.test.ts index 5066bdb9b8..b85109162a 100644 --- a/packages/core/test/integrations/expoupdateslistener.test.ts +++ b/packages/core/test/integrations/expoupdateslistener.test.ts @@ -1,10 +1,4 @@ -import { - addBreadcrumb, - type Span, - SPAN_STATUS_ERROR, - SPAN_STATUS_OK, - startInactiveSpan, -} from '@sentry/core'; +import { addBreadcrumb, type Span, SPAN_STATUS_ERROR, SPAN_STATUS_OK, startInactiveSpan } from '@sentry/core'; import { expoUpdatesListenerIntegration, diff --git a/packages/core/test/integrations/turboModuleContext.spans.test.ts b/packages/core/test/integrations/turboModuleContext.spans.test.ts index 28023ca43d..3b866c59ae 100644 --- a/packages/core/test/integrations/turboModuleContext.spans.test.ts +++ b/packages/core/test/integrations/turboModuleContext.spans.test.ts @@ -14,12 +14,7 @@ */ import type { Event, Span, TransactionEvent } from '@sentry/core'; -import { - setCurrentClient, - spanToJSON, - startNewTrace, - startSpanManual, -} from '@sentry/core'; +import { setCurrentClient, spanToJSON, startNewTrace, startSpanManual } from '@sentry/core'; import { turboModuleContextIntegration } from '../../src/js/integrations/turboModuleContext'; import { _resetTurboModuleAggregator } from '../../src/js/turbomodule/turboModuleAggregator'; diff --git a/packages/core/test/mocks/client.ts b/packages/core/test/mocks/client.ts index c7de8339e5..2e68a6db47 100644 --- a/packages/core/test/mocks/client.ts +++ b/packages/core/test/mocks/client.ts @@ -3,6 +3,7 @@ import type { Event, EventHint, Integration, Outcome, ParameterizedString, Sessi import { Client, createTransport, initAndBind, resolvedSyncPromise, setCurrentClient } from '@sentry/core'; import type { ReactNativeClientOptions } from '../../src/js/options'; + import { clearAllScopes } from '../testutils'; export function getDefaultTestClientOptions(options: Partial = {}): TestClientOptions { diff --git a/packages/core/test/tracing/integrations/stallTracking/stalltracking.test.ts b/packages/core/test/tracing/integrations/stallTracking/stalltracking.test.ts index 06dd42a67e..f71414565c 100644 --- a/packages/core/test/tracing/integrations/stallTracking/stalltracking.test.ts +++ b/packages/core/test/tracing/integrations/stallTracking/stalltracking.test.ts @@ -1,17 +1,11 @@ import type { Span } from '@sentry/core'; -import { - setCurrentClient, - startIdleSpan, - startSpan, - startSpanManual, - timestampInSeconds, -} from '@sentry/core'; +import { setCurrentClient, startIdleSpan, startSpan, startSpanManual, timestampInSeconds } from '@sentry/core'; import { stallTrackingIntegration } from '../../../../src/js/tracing/integrations/stalltracking'; import { getDefaultTestClientOptions, TestClient } from '../../../mocks/client'; -import { expectNonZeroStallMeasurements, expectStallMeasurements } from './stalltrackingutils'; import { clearAllScopes } from '../../../testutils'; +import { expectNonZeroStallMeasurements, expectStallMeasurements } from './stalltrackingutils'; jest.useFakeTimers({ advanceTimers: true, diff --git a/packages/core/test/tracing/reactnativenavigation.test.ts b/packages/core/test/tracing/reactnativenavigation.test.ts index ad2e0fbe03..de87c26908 100644 --- a/packages/core/test/tracing/reactnativenavigation.test.ts +++ b/packages/core/test/tracing/reactnativenavigation.test.ts @@ -1,11 +1,7 @@ import type { Event, StartSpanOptions } from '@sentry/core'; import type { EmitterSubscription } from 'react-native'; -import { - getActiveSpan, - setCurrentClient, - spanToJSON, -} from '@sentry/core'; +import { getActiveSpan, setCurrentClient, spanToJSON } from '@sentry/core'; import type { BottomTabPressedEvent, diff --git a/packages/core/test/tracing/reactnavigation.stalltracking.test.ts b/packages/core/test/tracing/reactnavigation.stalltracking.test.ts index 00ace05a9f..b2c37104aa 100644 --- a/packages/core/test/tracing/reactnavigation.stalltracking.test.ts +++ b/packages/core/test/tracing/reactnavigation.stalltracking.test.ts @@ -10,9 +10,9 @@ import { stallTrackingIntegration } from '../../src/js/tracing/integrations/stal import { isNearToNow } from '../../src/js/tracing/utils'; import { RN_GLOBAL_OBJ } from '../../src/js/utils/worldwide'; import { getDefaultTestClientOptions, TestClient } from '../mocks/client'; +import { clearAllScopes } from '../testutils'; import { expectStallMeasurements } from './integrations/stallTracking/stalltrackingutils'; import { createMockNavigationAndAttachTo } from './reactnavigationutils'; -import { clearAllScopes } from '../testutils'; jest.useFakeTimers({ advanceTimers: true, diff --git a/packages/core/test/tracing/reactnavigation.test.ts b/packages/core/test/tracing/reactnavigation.test.ts index b0e07daab3..521ba3f85d 100644 --- a/packages/core/test/tracing/reactnavigation.test.ts +++ b/packages/core/test/tracing/reactnavigation.test.ts @@ -1,11 +1,7 @@ import type { Event, Measurements, SentrySpan, StartSpanOptions } from '@sentry/core'; import * as core from '@sentry/core'; -import { - getActiveSpan, - setCurrentClient, - spanToJSON, -} from '@sentry/core'; +import { getActiveSpan, setCurrentClient, spanToJSON } from '@sentry/core'; import type { NavigationRoute } from '../../src/js/tracing/reactnavigation'; import type { UnsafeAction } from '../../src/js/vendor/react-navigation/types'; @@ -35,9 +31,9 @@ import { RN_GLOBAL_OBJ } from '../../src/js/utils/worldwide'; import { mockAppRegistryIntegration } from '../mocks/appRegistryIntegrationMock'; import { getDefaultTestClientOptions, TestClient } from '../mocks/client'; import { NATIVE } from '../mockWrapper'; +import { clearAllScopes } from '../testutils'; import { getDevServer } from './../../src/js/integrations/debugsymbolicatorutils'; import { createMockNavigationAndAttachTo, createMockNavigationWithNestedState } from './reactnavigationutils'; -import { clearAllScopes } from '../testutils'; const dummyRoute = { name: 'Route', diff --git a/packages/core/test/tracing/timetodisplay.test.tsx b/packages/core/test/tracing/timetodisplay.test.tsx index 8440c00078..c51d427b09 100644 --- a/packages/core/test/tracing/timetodisplay.test.tsx +++ b/packages/core/test/tracing/timetodisplay.test.tsx @@ -1,12 +1,6 @@ import type { Event, Measurements, Span, SpanJSON } from '@sentry/core'; -import { - debug, - setCurrentClient, - spanToJSON, - startSpan, - startSpanManual, -} from '@sentry/core'; +import { debug, setCurrentClient, spanToJSON, startSpan, startSpanManual } from '@sentry/core'; jest.spyOn(debug, 'warn');