@sentry/react-router 11.0.0-alpha.2 → 11.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/build/cjs/client/createClientInstrumentation.js +3 -3
  2. package/build/cjs/client/createClientInstrumentation.js.map +1 -1
  3. package/build/cjs/client/hydratedRouter.js +2 -1
  4. package/build/cjs/client/hydratedRouter.js.map +1 -1
  5. package/build/cjs/server/createSentryHandleError.js +2 -1
  6. package/build/cjs/server/createSentryHandleError.js.map +1 -1
  7. package/build/cjs/server/createServerInstrumentation.js +5 -5
  8. package/build/cjs/server/createServerInstrumentation.js.map +1 -1
  9. package/build/cjs/server/wrapSentryHandleRequest.js +2 -1
  10. package/build/cjs/server/wrapSentryHandleRequest.js.map +1 -1
  11. package/build/esm/client/createClientInstrumentation.js +5 -5
  12. package/build/esm/client/createClientInstrumentation.js.map +1 -1
  13. package/build/esm/client/hydratedRouter.js +3 -2
  14. package/build/esm/client/hydratedRouter.js.map +1 -1
  15. package/build/esm/package.json +1 -1
  16. package/build/esm/server/createSentryHandleError.js +2 -1
  17. package/build/esm/server/createSentryHandleError.js.map +1 -1
  18. package/build/esm/server/createServerInstrumentation.js +5 -5
  19. package/build/esm/server/createServerInstrumentation.js.map +1 -1
  20. package/build/esm/server/wrapSentryHandleRequest.js +2 -1
  21. package/build/esm/server/wrapSentryHandleRequest.js.map +1 -1
  22. package/build/types/client/createClientInstrumentation.d.ts.map +1 -1
  23. package/build/types/index.types.d.ts +0 -1
  24. package/build/types/index.types.d.ts.map +1 -1
  25. package/build/types/server/createSentryHandleError.d.ts.map +1 -1
  26. package/build/types/server/createServerInstrumentation.d.ts.map +1 -1
  27. package/package.json +8 -7
@@ -47,7 +47,7 @@ function createSentryClientInstrumentation(options = {}) {
47
47
  name: core.hasSpanStreamingEnabled(client) ? core.NAVIGATION_SPAN_NAME_FALLBACK : pathname,
48
48
  attributes: {
49
49
  [attributes.SENTRY_SEGMENT_NAME_SOURCE]: "url",
50
- [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: "navigation",
50
+ [attributes.SENTRY_OP]: op.NAVIGATION,
51
51
  [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.navigation.react_router.instrumentation_api",
52
52
  "navigation.type": "browser.popstate"
53
53
  }
@@ -83,7 +83,7 @@ function createSentryClientInstrumentation(options = {}) {
83
83
  name: core.hasSpanStreamingEnabled(client2) ? core.NAVIGATION_SPAN_NAME_FALLBACK : currentPathname,
84
84
  attributes: {
85
85
  [attributes.SENTRY_SEGMENT_NAME_SOURCE]: "url",
86
- [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: "navigation",
86
+ [attributes.SENTRY_OP]: op.NAVIGATION,
87
87
  [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.navigation.react_router.instrumentation_api",
88
88
  "navigation.type": navigationType
89
89
  }
@@ -122,7 +122,7 @@ function createSentryClientInstrumentation(options = {}) {
122
122
  name: core.hasSpanStreamingEnabled(client) ? core.NAVIGATION_SPAN_NAME_FALLBACK : toPath,
123
123
  attributes: {
124
124
  [attributes.SENTRY_SEGMENT_NAME_SOURCE]: "url",
125
- [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: "navigation",
125
+ [attributes.SENTRY_OP]: op.NAVIGATION,
126
126
  [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.navigation.react_router.instrumentation_api",
127
127
  "navigation.type": "router.navigate"
128
128
  }
@@ -1 +1 @@
1
- {"version":3,"file":"createClientInstrumentation.js","sources":["../../../src/client/createClientInstrumentation.ts"],"sourcesContent":["// oxlint-disable max-lines\nimport { getAbsoluteUrl, startBrowserTracingNavigationSpan } from '@sentry/browser';\nimport type { Span } from '@sentry/core';\nimport {\n debug,\n getActiveSpan,\n getClient,\n getRootSpan,\n GLOBAL_OBJ,\n hasSpanStreamingEnabled,\n NAVIGATION_SPAN_NAME_FALLBACK,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n spanToJSON,\n SPAN_STATUS_ERROR,\n updateSpanName,\n filterCollectedUrl,\n} from '@sentry/core';\nimport { startSpan } from '@sentry/core/browser';\nimport type { ClientInstrumentation } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport { captureInstrumentationError, getPathFromRequest, getPattern, normalizeRoutePath } from '../common/utils';\nimport {\n resolveNavigateAbsoluteUrl,\n resolveNavigateArg,\n finalizeNavigationSpanFromHydratedRouter,\n updateNavigationSpanUrlFromLocation,\n} from './utils';\nimport {\n SENTRY_SEGMENT_NAME_SOURCE,\n CODE_FUNCTION_NAME,\n SENTRY_OP,\n URL_FULL,\n URL_TEMPLATE,\n} from '@sentry/conventions/attributes';\nimport { FUNCTION, MIDDLEWARE } from '@sentry/conventions/op';\n\nconst WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window;\n\n// Tracks active numeric navigation span to prevent duplicate spans when popstate fires\nlet currentNumericNavigationSpan: Span | undefined;\n\n// Per-request middleware counters, keyed by Request\nconst middlewareCountersMap = new WeakMap<object, Record<string, number>>();\n\nconst SENTRY_CLIENT_INSTRUMENTATION_FLAG = '__sentryReactRouterClientInstrumentationUsed';\n// Intentionally never reset - once set, instrumentation API handles all navigations for the session.\nconst SENTRY_NAVIGATE_HOOK_INVOKED_FLAG = '__sentryReactRouterNavigateHookInvoked';\nconst SENTRY_POPSTATE_LISTENER_ADDED_FLAG = '__sentryReactRouterPopstateListenerAdded';\n\ntype GlobalObjWithFlags = typeof GLOBAL_OBJ & {\n [SENTRY_CLIENT_INSTRUMENTATION_FLAG]?: boolean;\n [SENTRY_NAVIGATE_HOOK_INVOKED_FLAG]?: boolean;\n [SENTRY_POPSTATE_LISTENER_ADDED_FLAG]?: boolean;\n};\n\nconst GLOBAL_WITH_FLAGS = GLOBAL_OBJ as GlobalObjWithFlags;\n\n/**\n * Options for creating Sentry client instrumentation.\n */\nexport interface CreateSentryClientInstrumentationOptions {\n /**\n * Whether to capture errors from loaders/actions automatically.\n * Set to `false` to avoid duplicates if using custom error handlers.\n * @default true\n */\n captureErrors?: boolean;\n}\n\n/**\n * Creates a Sentry client instrumentation for React Router's instrumentation API.\n */\nexport function createSentryClientInstrumentation(\n options: CreateSentryClientInstrumentationOptions = {},\n): ClientInstrumentation {\n const { captureErrors = true } = options;\n\n DEBUG_BUILD && debug.log('React Router client instrumentation API created.');\n\n return {\n router(router) {\n // Set the flag when React Router actually invokes our instrumentation.\n // This ensures the flag is only set in Library Mode (where hooks run),\n // not in Framework Mode (where hooks are never called).\n // See: https://github.com/remix-run/react-router/discussions/13749\n GLOBAL_WITH_FLAGS[SENTRY_CLIENT_INSTRUMENTATION_FLAG] = true;\n DEBUG_BUILD && debug.log('React Router client instrumentation API router hook registered.');\n\n // Add popstate listener for browser back/forward navigation (persists for session, one listener only)\n if (!GLOBAL_WITH_FLAGS[SENTRY_POPSTATE_LISTENER_ADDED_FLAG] && WINDOW.addEventListener) {\n GLOBAL_WITH_FLAGS[SENTRY_POPSTATE_LISTENER_ADDED_FLAG] = true;\n\n WINDOW.addEventListener('popstate', () => {\n const client = getClient();\n if (!client) {\n currentNumericNavigationSpan = undefined;\n return;\n }\n\n const pathname = WINDOW.location?.pathname || '/';\n\n // If there's an active numeric navigation span, update it instead of creating a duplicate\n if (currentNumericNavigationSpan) {\n if (currentNumericNavigationSpan.isRecording()) {\n updateNavigationSpanUrlFromLocation(currentNumericNavigationSpan);\n }\n currentNumericNavigationSpan = undefined;\n return;\n }\n\n // Only create a new span for actual browser back/forward button clicks\n startBrowserTracingNavigationSpan(\n client,\n {\n // With span streaming, span names have to be low cardinality, so we can't fall back to\n // the URL. The route hooks parameterize the span once they resolve.\n name: hasSpanStreamingEnabled(client) ? NAVIGATION_SPAN_NAME_FALLBACK : pathname,\n attributes: {\n [SENTRY_SEGMENT_NAME_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router.instrumentation_api',\n 'navigation.type': 'browser.popstate',\n },\n },\n { url: getAbsoluteUrl(pathname) },\n );\n });\n\n DEBUG_BUILD && debug.log('React Router popstate listener registered for browser back/forward navigation.');\n }\n\n router.instrument({\n async navigate(callNavigate, info) {\n // navigate(0) triggers a page reload - skip span creation, but still capture errors\n // (navigation can be rejected before reload, e.g., by a navigation guard)\n if (info.to === 0) {\n const result = await callNavigate();\n if (result.status === 'error' && result.error instanceof Error) {\n captureInstrumentationError(result, captureErrors, 'react_router.navigate', {\n [URL_FULL]: filterCollectedUrl(info.currentUrl),\n });\n }\n return;\n }\n\n GLOBAL_WITH_FLAGS[SENTRY_NAVIGATE_HOOK_INVOKED_FLAG] = true;\n\n // Handle numeric navigations (navigate(-1), navigate(1), etc.)\n if (typeof info.to === 'number') {\n const client = getClient();\n let navigationSpan;\n\n if (client) {\n const navigationType = info.to < 0 ? 'router.back' : 'router.forward';\n const currentPathname = WINDOW.location?.pathname || info.currentUrl;\n\n navigationSpan = startBrowserTracingNavigationSpan(\n client,\n {\n // With span streaming, span names have to be low cardinality, so we can't fall back\n // to the URL. The route is resolved once the navigation settles.\n name: hasSpanStreamingEnabled(client) ? NAVIGATION_SPAN_NAME_FALLBACK : currentPathname,\n attributes: {\n [SENTRY_SEGMENT_NAME_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router.instrumentation_api',\n 'navigation.type': navigationType,\n },\n },\n { url: getAbsoluteUrl(currentPathname) },\n );\n\n // Store ref so popstate listener can update it instead of creating a duplicate\n currentNumericNavigationSpan = navigationSpan;\n }\n\n try {\n const result = await callNavigate();\n\n if (navigationSpan && WINDOW.location) {\n finalizeNavigationSpanFromHydratedRouter(navigationSpan);\n }\n\n if (result.status === 'error' && result.error instanceof Error) {\n if (navigationSpan) {\n navigationSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n }\n captureInstrumentationError(result, captureErrors, 'react_router.navigate', {\n [URL_FULL]: WINDOW.location?.pathname || filterCollectedUrl(info.currentUrl),\n });\n }\n } finally {\n currentNumericNavigationSpan = undefined;\n }\n return;\n }\n\n // Handle string/object navigations (e.g., navigate('/about') or navigate({ pathname: '/about' }))\n const client = getClient();\n const toPath = resolveNavigateArg(info.to);\n let navigationSpan;\n\n if (client) {\n navigationSpan = startBrowserTracingNavigationSpan(\n client,\n {\n // With span streaming, span names have to be low cardinality, so we can't fall back to\n // the URL. The route hooks parameterize the span once they resolve.\n name: hasSpanStreamingEnabled(client) ? NAVIGATION_SPAN_NAME_FALLBACK : toPath,\n attributes: {\n [SENTRY_SEGMENT_NAME_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router.instrumentation_api',\n 'navigation.type': 'router.navigate',\n },\n },\n { url: resolveNavigateAbsoluteUrl(info.to, info.currentUrl) },\n );\n }\n\n const result = await callNavigate();\n if (result.status === 'error' && result.error instanceof Error) {\n if (navigationSpan) {\n navigationSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n }\n captureInstrumentationError(result, captureErrors, 'react_router.navigate', {\n [URL_FULL]: filterCollectedUrl(toPath),\n });\n }\n return;\n },\n\n async fetch(callFetch, info) {\n await startSpan(\n {\n name: `Fetcher ${info.fetcherKey}`,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'fetcher',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callFetch();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.fetcher', {\n [URL_FULL]: filterCollectedUrl(info.href),\n });\n }\n },\n );\n },\n });\n },\n\n route(route) {\n const routeId = route.id;\n\n route.instrument({\n async loader(callLoader, info) {\n const urlPath = getPathFromRequest(info.request);\n const pattern = normalizeRoutePath(getPattern(info));\n const routePattern = pattern || urlPath;\n // Parameterize the active navigation root span. (Route hooks don't fire on initial\n // pageload, so this only affects navigations.)\n updateRootSpanRoute(routePattern, !!pattern);\n\n await startSpan(\n {\n name: routePattern,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'clientLoader',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callLoader();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_loader', {\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async action(callAction, info) {\n const urlPath = getPathFromRequest(info.request);\n const pattern = normalizeRoutePath(getPattern(info));\n const routePattern = pattern || urlPath;\n updateRootSpanRoute(routePattern, !!pattern);\n\n await startSpan(\n {\n name: routePattern,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'clientAction',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callAction();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_action', {\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async middleware(callMiddleware, info) {\n const urlPath = getPathFromRequest(info.request);\n const routePattern = normalizeRoutePath(getPattern(info)) || urlPath;\n\n let counters = middlewareCountersMap.get(info.request);\n if (!counters) {\n counters = {};\n middlewareCountersMap.set(info.request, counters);\n }\n\n const middlewareIndex = counters[routeId] ?? 0;\n counters[routeId] = middlewareIndex + 1;\n\n await startSpan(\n {\n name: `middleware ${routeId}`,\n attributes: {\n [SENTRY_OP]: MIDDLEWARE,\n [CODE_FUNCTION_NAME]: 'clientMiddleware',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n 'react_router.route.id': routeId,\n 'http.route': routePattern,\n 'react_router.middleware.index': middlewareIndex,\n },\n },\n async span => {\n const result = await callMiddleware();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_middleware', {\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async lazy(callLazy) {\n await startSpan(\n {\n name: 'Lazy Route Load',\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'lazy',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callLazy();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_lazy', {});\n }\n },\n );\n },\n });\n },\n };\n}\n\n/**\n * Updates the active navigation/pageload root span name with the parameterized route, so the\n * transaction reflects the parameterized route pattern (e.g. `/users/:id`).\n */\nfunction updateRootSpanRoute(routeName: string, hasPattern: boolean): void {\n if (!hasPattern) {\n return;\n }\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan && getRootSpan(activeSpan);\n if (!rootSpan) {\n return;\n }\n\n const { attributes } = spanToJSON(rootSpan);\n const op = attributes[SENTRY_OP];\n if (op !== 'navigation' && op !== 'pageload') {\n return;\n }\n\n updateSpanName(rootSpan, routeName);\n rootSpan.setAttributes({ [SENTRY_SEGMENT_NAME_SOURCE]: 'route', [URL_TEMPLATE]: routeName });\n}\n\n/**\n * Check if React Router's instrumentation API is being used on the client.\n */\nexport function isClientInstrumentationApiUsed(): boolean {\n return !!GLOBAL_WITH_FLAGS[SENTRY_CLIENT_INSTRUMENTATION_FLAG];\n}\n\n/**\n * Check if React Router's instrumentation API's navigate hook was invoked.\n */\nexport function isNavigateHookInvoked(): boolean {\n return !!GLOBAL_WITH_FLAGS[SENTRY_NAVIGATE_HOOK_INVOKED_FLAG];\n}\n"],"names":["GLOBAL_OBJ","DEBUG_BUILD","debug","getClient","updateNavigationSpanUrlFromLocation","startBrowserTracingNavigationSpan","hasSpanStreamingEnabled","NAVIGATION_SPAN_NAME_FALLBACK","SENTRY_SEGMENT_NAME_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","getAbsoluteUrl","result","captureInstrumentationError","URL_FULL","filterCollectedUrl","client","navigationSpan","finalizeNavigationSpanFromHydratedRouter","SPAN_STATUS_ERROR","resolveNavigateArg","resolveNavigateAbsoluteUrl","startSpan","SENTRY_OP","FUNCTION","CODE_FUNCTION_NAME","getPathFromRequest","normalizeRoutePath","getPattern","MIDDLEWARE","getActiveSpan","getRootSpan","attributes","spanToJSON","updateSpanName","URL_TEMPLATE"],"mappings":"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"}
1
+ {"version":3,"file":"createClientInstrumentation.js","sources":["../../../src/client/createClientInstrumentation.ts"],"sourcesContent":["// oxlint-disable max-lines\nimport { getAbsoluteUrl, startBrowserTracingNavigationSpan } from '@sentry/browser';\nimport type { Span } from '@sentry/core';\nimport {\n debug,\n getActiveSpan,\n getClient,\n getRootSpan,\n GLOBAL_OBJ,\n hasSpanStreamingEnabled,\n NAVIGATION_SPAN_NAME_FALLBACK,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n spanToJSON,\n SPAN_STATUS_ERROR,\n updateSpanName,\n filterCollectedUrl,\n} from '@sentry/core';\nimport { startSpan } from '@sentry/core/browser';\nimport type { ClientInstrumentation } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport { captureInstrumentationError, getPathFromRequest, getPattern, normalizeRoutePath } from '../common/utils';\nimport {\n resolveNavigateAbsoluteUrl,\n resolveNavigateArg,\n finalizeNavigationSpanFromHydratedRouter,\n updateNavigationSpanUrlFromLocation,\n} from './utils';\nimport {\n SENTRY_SEGMENT_NAME_SOURCE,\n CODE_FUNCTION_NAME,\n SENTRY_OP,\n URL_FULL,\n URL_TEMPLATE,\n} from '@sentry/conventions/attributes';\nimport { FUNCTION, MIDDLEWARE, NAVIGATION } from '@sentry/conventions/op';\n\nconst WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window;\n\n// Tracks active numeric navigation span to prevent duplicate spans when popstate fires\nlet currentNumericNavigationSpan: Span | undefined;\n\n// Per-request middleware counters, keyed by Request\nconst middlewareCountersMap = new WeakMap<object, Record<string, number>>();\n\nconst SENTRY_CLIENT_INSTRUMENTATION_FLAG = '__sentryReactRouterClientInstrumentationUsed';\n// Intentionally never reset - once set, instrumentation API handles all navigations for the session.\nconst SENTRY_NAVIGATE_HOOK_INVOKED_FLAG = '__sentryReactRouterNavigateHookInvoked';\nconst SENTRY_POPSTATE_LISTENER_ADDED_FLAG = '__sentryReactRouterPopstateListenerAdded';\n\ntype GlobalObjWithFlags = typeof GLOBAL_OBJ & {\n [SENTRY_CLIENT_INSTRUMENTATION_FLAG]?: boolean;\n [SENTRY_NAVIGATE_HOOK_INVOKED_FLAG]?: boolean;\n [SENTRY_POPSTATE_LISTENER_ADDED_FLAG]?: boolean;\n};\n\nconst GLOBAL_WITH_FLAGS = GLOBAL_OBJ as GlobalObjWithFlags;\n\n/**\n * Options for creating Sentry client instrumentation.\n */\nexport interface CreateSentryClientInstrumentationOptions {\n /**\n * Whether to capture errors from loaders/actions automatically.\n * Set to `false` to avoid duplicates if using custom error handlers.\n * @default true\n */\n captureErrors?: boolean;\n}\n\n/**\n * Creates a Sentry client instrumentation for React Router's instrumentation API.\n */\nexport function createSentryClientInstrumentation(\n options: CreateSentryClientInstrumentationOptions = {},\n): ClientInstrumentation {\n const { captureErrors = true } = options;\n\n DEBUG_BUILD && debug.log('React Router client instrumentation API created.');\n\n return {\n router(router) {\n // Set the flag when React Router actually invokes our instrumentation.\n // This ensures the flag is only set in Library Mode (where hooks run),\n // not in Framework Mode (where hooks are never called).\n // See: https://github.com/remix-run/react-router/discussions/13749\n GLOBAL_WITH_FLAGS[SENTRY_CLIENT_INSTRUMENTATION_FLAG] = true;\n DEBUG_BUILD && debug.log('React Router client instrumentation API router hook registered.');\n\n // Add popstate listener for browser back/forward navigation (persists for session, one listener only)\n if (!GLOBAL_WITH_FLAGS[SENTRY_POPSTATE_LISTENER_ADDED_FLAG] && WINDOW.addEventListener) {\n GLOBAL_WITH_FLAGS[SENTRY_POPSTATE_LISTENER_ADDED_FLAG] = true;\n\n WINDOW.addEventListener('popstate', () => {\n const client = getClient();\n if (!client) {\n currentNumericNavigationSpan = undefined;\n return;\n }\n\n const pathname = WINDOW.location?.pathname || '/';\n\n // If there's an active numeric navigation span, update it instead of creating a duplicate\n if (currentNumericNavigationSpan) {\n if (currentNumericNavigationSpan.isRecording()) {\n updateNavigationSpanUrlFromLocation(currentNumericNavigationSpan);\n }\n currentNumericNavigationSpan = undefined;\n return;\n }\n\n // Only create a new span for actual browser back/forward button clicks\n startBrowserTracingNavigationSpan(\n client,\n {\n // With span streaming, span names have to be low cardinality, so we can't fall back to\n // the URL. The route hooks parameterize the span once they resolve.\n name: hasSpanStreamingEnabled(client) ? NAVIGATION_SPAN_NAME_FALLBACK : pathname,\n attributes: {\n [SENTRY_SEGMENT_NAME_SOURCE]: 'url',\n [SENTRY_OP]: NAVIGATION,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router.instrumentation_api',\n 'navigation.type': 'browser.popstate',\n },\n },\n { url: getAbsoluteUrl(pathname) },\n );\n });\n\n DEBUG_BUILD && debug.log('React Router popstate listener registered for browser back/forward navigation.');\n }\n\n router.instrument({\n async navigate(callNavigate, info) {\n // navigate(0) triggers a page reload - skip span creation, but still capture errors\n // (navigation can be rejected before reload, e.g., by a navigation guard)\n if (info.to === 0) {\n const result = await callNavigate();\n if (result.status === 'error' && result.error instanceof Error) {\n captureInstrumentationError(result, captureErrors, 'react_router.navigate', {\n [URL_FULL]: filterCollectedUrl(info.currentUrl),\n });\n }\n return;\n }\n\n GLOBAL_WITH_FLAGS[SENTRY_NAVIGATE_HOOK_INVOKED_FLAG] = true;\n\n // Handle numeric navigations (navigate(-1), navigate(1), etc.)\n if (typeof info.to === 'number') {\n const client = getClient();\n let navigationSpan;\n\n if (client) {\n const navigationType = info.to < 0 ? 'router.back' : 'router.forward';\n const currentPathname = WINDOW.location?.pathname || info.currentUrl;\n\n navigationSpan = startBrowserTracingNavigationSpan(\n client,\n {\n // With span streaming, span names have to be low cardinality, so we can't fall back\n // to the URL. The route is resolved once the navigation settles.\n name: hasSpanStreamingEnabled(client) ? NAVIGATION_SPAN_NAME_FALLBACK : currentPathname,\n attributes: {\n [SENTRY_SEGMENT_NAME_SOURCE]: 'url',\n [SENTRY_OP]: NAVIGATION,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router.instrumentation_api',\n 'navigation.type': navigationType,\n },\n },\n { url: getAbsoluteUrl(currentPathname) },\n );\n\n // Store ref so popstate listener can update it instead of creating a duplicate\n currentNumericNavigationSpan = navigationSpan;\n }\n\n try {\n const result = await callNavigate();\n\n if (navigationSpan && WINDOW.location) {\n finalizeNavigationSpanFromHydratedRouter(navigationSpan);\n }\n\n if (result.status === 'error' && result.error instanceof Error) {\n if (navigationSpan) {\n navigationSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n }\n captureInstrumentationError(result, captureErrors, 'react_router.navigate', {\n [URL_FULL]: WINDOW.location?.pathname || filterCollectedUrl(info.currentUrl),\n });\n }\n } finally {\n currentNumericNavigationSpan = undefined;\n }\n return;\n }\n\n // Handle string/object navigations (e.g., navigate('/about') or navigate({ pathname: '/about' }))\n const client = getClient();\n const toPath = resolveNavigateArg(info.to);\n let navigationSpan;\n\n if (client) {\n navigationSpan = startBrowserTracingNavigationSpan(\n client,\n {\n // With span streaming, span names have to be low cardinality, so we can't fall back to\n // the URL. The route hooks parameterize the span once they resolve.\n name: hasSpanStreamingEnabled(client) ? NAVIGATION_SPAN_NAME_FALLBACK : toPath,\n attributes: {\n [SENTRY_SEGMENT_NAME_SOURCE]: 'url',\n [SENTRY_OP]: NAVIGATION,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router.instrumentation_api',\n 'navigation.type': 'router.navigate',\n },\n },\n { url: resolveNavigateAbsoluteUrl(info.to, info.currentUrl) },\n );\n }\n\n const result = await callNavigate();\n if (result.status === 'error' && result.error instanceof Error) {\n if (navigationSpan) {\n navigationSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n }\n captureInstrumentationError(result, captureErrors, 'react_router.navigate', {\n [URL_FULL]: filterCollectedUrl(toPath),\n });\n }\n return;\n },\n\n async fetch(callFetch, info) {\n await startSpan(\n {\n name: `Fetcher ${info.fetcherKey}`,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'fetcher',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callFetch();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.fetcher', {\n [URL_FULL]: filterCollectedUrl(info.href),\n });\n }\n },\n );\n },\n });\n },\n\n route(route) {\n const routeId = route.id;\n\n route.instrument({\n async loader(callLoader, info) {\n const urlPath = getPathFromRequest(info.request);\n const pattern = normalizeRoutePath(getPattern(info));\n const routePattern = pattern || urlPath;\n // Parameterize the active navigation root span. (Route hooks don't fire on initial\n // pageload, so this only affects navigations.)\n updateRootSpanRoute(routePattern, !!pattern);\n\n await startSpan(\n {\n name: routePattern,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'clientLoader',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callLoader();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_loader', {\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async action(callAction, info) {\n const urlPath = getPathFromRequest(info.request);\n const pattern = normalizeRoutePath(getPattern(info));\n const routePattern = pattern || urlPath;\n updateRootSpanRoute(routePattern, !!pattern);\n\n await startSpan(\n {\n name: routePattern,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'clientAction',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callAction();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_action', {\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async middleware(callMiddleware, info) {\n const urlPath = getPathFromRequest(info.request);\n const routePattern = normalizeRoutePath(getPattern(info)) || urlPath;\n\n let counters = middlewareCountersMap.get(info.request);\n if (!counters) {\n counters = {};\n middlewareCountersMap.set(info.request, counters);\n }\n\n const middlewareIndex = counters[routeId] ?? 0;\n counters[routeId] = middlewareIndex + 1;\n\n await startSpan(\n {\n name: `middleware ${routeId}`,\n attributes: {\n [SENTRY_OP]: MIDDLEWARE,\n [CODE_FUNCTION_NAME]: 'clientMiddleware',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n 'react_router.route.id': routeId,\n 'http.route': routePattern,\n 'react_router.middleware.index': middlewareIndex,\n },\n },\n async span => {\n const result = await callMiddleware();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_middleware', {\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async lazy(callLazy) {\n await startSpan(\n {\n name: 'Lazy Route Load',\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'lazy',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callLazy();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_lazy', {});\n }\n },\n );\n },\n });\n },\n };\n}\n\n/**\n * Updates the active navigation/pageload root span name with the parameterized route, so the\n * transaction reflects the parameterized route pattern (e.g. `/users/:id`).\n */\nfunction updateRootSpanRoute(routeName: string, hasPattern: boolean): void {\n if (!hasPattern) {\n return;\n }\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan && getRootSpan(activeSpan);\n if (!rootSpan) {\n return;\n }\n\n const { attributes } = spanToJSON(rootSpan);\n const op = attributes[SENTRY_OP];\n if (op !== 'navigation' && op !== 'pageload') {\n return;\n }\n\n updateSpanName(rootSpan, routeName);\n rootSpan.setAttributes({ [SENTRY_SEGMENT_NAME_SOURCE]: 'route', [URL_TEMPLATE]: routeName });\n}\n\n/**\n * Check if React Router's instrumentation API is being used on the client.\n */\nexport function isClientInstrumentationApiUsed(): boolean {\n return !!GLOBAL_WITH_FLAGS[SENTRY_CLIENT_INSTRUMENTATION_FLAG];\n}\n\n/**\n * Check if React Router's instrumentation API's navigate hook was invoked.\n */\nexport function isNavigateHookInvoked(): boolean {\n return !!GLOBAL_WITH_FLAGS[SENTRY_NAVIGATE_HOOK_INVOKED_FLAG];\n}\n"],"names":["GLOBAL_OBJ","DEBUG_BUILD","debug","getClient","updateNavigationSpanUrlFromLocation","startBrowserTracingNavigationSpan","hasSpanStreamingEnabled","NAVIGATION_SPAN_NAME_FALLBACK","SENTRY_SEGMENT_NAME_SOURCE","SENTRY_OP","NAVIGATION","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","getAbsoluteUrl","result","captureInstrumentationError","URL_FULL","filterCollectedUrl","client","navigationSpan","finalizeNavigationSpanFromHydratedRouter","SPAN_STATUS_ERROR","resolveNavigateArg","resolveNavigateAbsoluteUrl","startSpan","FUNCTION","CODE_FUNCTION_NAME","getPathFromRequest","normalizeRoutePath","getPattern","MIDDLEWARE","getActiveSpan","getRootSpan","attributes","spanToJSON","updateSpanName","URL_TEMPLATE"],"mappings":"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"}
@@ -6,6 +6,7 @@ const debugBuild = require('../common/debug-build.js');
6
6
  const createClientInstrumentation = require('./createClientInstrumentation.js');
7
7
  const utils = require('./utils.js');
8
8
  const attributes = require('@sentry/conventions/attributes');
9
+ const op = require('@sentry/conventions/op');
9
10
 
10
11
  const GLOBAL_OBJ_WITH_DATA_ROUTER = core.GLOBAL_OBJ;
11
12
  const WINDOW = core.GLOBAL_OBJ;
@@ -109,7 +110,7 @@ function maybeCreateNavigationTransaction(name, url, source) {
109
110
  name: !core.hasSpanStreamingEnabled(client) ? name : core.NAVIGATION_SPAN_NAME_FALLBACK,
110
111
  attributes: {
111
112
  [attributes.SENTRY_SEGMENT_NAME_SOURCE]: source,
112
- [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: "navigation",
113
+ [attributes.SENTRY_OP]: op.NAVIGATION,
113
114
  [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.navigation.react_router",
114
115
  ...{}
115
116
  }
@@ -1 +1 @@
1
- {"version":3,"file":"hydratedRouter.js","sources":["../../../src/client/hydratedRouter.ts"],"sourcesContent":["import { getAbsoluteUrl, startBrowserTracingNavigationSpan } from '@sentry/browser';\nimport type { Span } from '@sentry/core';\nimport {\n debug,\n getActiveSpan,\n getClient,\n getRootSpan,\n GLOBAL_OBJ,\n hasSpanStreamingEnabled,\n isThenable,\n NAVIGATION_SPAN_NAME_FALLBACK,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n spanToJSON,\n} from '@sentry/core';\nimport type { DataRouter } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport { isClientInstrumentationApiUsed } from './createClientInstrumentation';\nimport {\n finalizeNavigationSpanFromRouterState,\n normalizePathname,\n resolveNavigateAbsoluteUrl,\n resolveNavigateArg,\n updateSpanWithParameterizedRoute,\n} from './utils';\nimport { SENTRY_SEGMENT_NAME_SOURCE, SENTRY_OP, URL_PATH, URL_TEMPLATE } from '@sentry/conventions/attributes';\n\nconst GLOBAL_OBJ_WITH_DATA_ROUTER = GLOBAL_OBJ as typeof GLOBAL_OBJ & {\n __reactRouterDataRouter?: DataRouter;\n};\n\nconst WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window;\n\nconst MAX_RETRIES = 40; // 2 seconds at 50ms interval\n\n/**\n * Instruments the React Router Data Router for pageloads and navigation.\n *\n * This function waits for the router to be available after hydration, then:\n * 1. Updates the pageload transaction with parameterized route info\n * 2. Patches router.navigate() to create navigation transactions\n * 3. Subscribes to router state changes to update navigation transactions with parameterized routes\n */\nexport function instrumentHydratedRouter(): void {\n function trySubscribe(): boolean {\n const router = GLOBAL_OBJ_WITH_DATA_ROUTER.__reactRouterDataRouter;\n\n if (router) {\n // The first time we hit the router, we try to update the pageload transaction\n const pageloadSpan = getActiveRootSpan();\n\n if (pageloadSpan) {\n // Matched against `url.path` rather than the span name: with span streaming, the pageload\n // span is named `Pageload` until a route is resolved, so the name may not hold the pathname.\n const pageloadPath = spanToJSON(pageloadSpan).attributes[URL_PATH];\n if (\n typeof pageloadPath === 'string' &&\n // this event is for the currently active pageload\n normalizePathname(router.state.location.pathname) === normalizePathname(pageloadPath)\n ) {\n pageloadSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.pageload.react_router');\n updateSpanWithParameterizedRoute(pageloadSpan, router.state);\n }\n }\n\n // Patching navigate for creating accurate navigation transactions\n if (typeof router.navigate === 'function') {\n const originalNav = router.navigate.bind(router);\n router.navigate = function sentryPatchedNavigate(...args) {\n // Skip if instrumentation API is enabled (it handles navigation spans itself)\n if (!isClientInstrumentationApiUsed()) {\n const target = args[0];\n\n if (typeof target === 'number') {\n // navigate(0) triggers a reload, not a route change — skip span creation\n if (target !== 0) {\n const currentPathname = WINDOW.location?.pathname || '/';\n const navigationSpan = maybeCreateNavigationTransaction(\n currentPathname,\n getAbsoluteUrl(currentPathname),\n 'url',\n );\n\n const result = originalNav(...args);\n\n // Numeric navigations (`navigate(-1)`/`navigate(1)`) don't carry a destination\n // path, so we can only resolve the real URL/route once the router has settled.\n if (navigationSpan) {\n // Finalize from the (updated) router state after navigation completes, in both\n // the resolve and reject paths, so a rejected navigation still ends up with the\n // correct URL attributes instead of the placeholder start pathname.\n if (isThenable(result)) {\n result.then(\n () => finalizeNavigationSpanFromRouterState(navigationSpan, router.state),\n () => finalizeNavigationSpanFromRouterState(navigationSpan, router.state),\n );\n } else {\n finalizeNavigationSpanFromRouterState(navigationSpan, router.state);\n }\n }\n\n return result;\n }\n } else {\n maybeCreateNavigationTransaction(\n resolveNavigateArg(target) || '<unknown route>',\n resolveNavigateAbsoluteUrl(target),\n 'url',\n );\n }\n }\n return originalNav(...args);\n };\n }\n\n // Subscribe to router state changes to update navigation transactions (and any pageload\n // whose route info only became available after `trySubscribe`, e.g. lazy routes) with the\n // parameterized route.\n router.subscribe(newState => {\n const rootSpan = getActiveRootSpan();\n\n if (!rootSpan) {\n return;\n }\n\n const rootSpanJson = spanToJSON(rootSpan);\n const rootSpanAttributes = rootSpanJson.attributes;\n\n // When the instrumentation API is active, navigation roots are parameterized\n // by the native route hooks\n if (\n rootSpanAttributes[SENTRY_OP] === 'navigation' &&\n isClientInstrumentationApiUsed() &&\n rootSpanAttributes[SENTRY_SEGMENT_NAME_SOURCE] === 'route'\n ) {\n return;\n }\n\n const rootSpanName = rootSpanJson.name;\n const spanPathname = rootSpanAttributes[URL_PATH] as string | undefined;\n const destinationPathname = normalizePathname(newState.location.pathname);\n\n if (\n rootSpanName &&\n newState.navigation.state === 'idle' && // navigation has completed\n // this event is for the currently active root span\n (destinationPathname === normalizePathname(rootSpanName) ||\n (spanPathname && destinationPathname === normalizePathname(spanPathname)))\n ) {\n updateSpanWithParameterizedRoute(rootSpan, newState);\n }\n });\n return true;\n }\n return false;\n }\n\n // Wait until the router is available (since the SDK loads before hydration)\n if (!trySubscribe()) {\n let retryCount = 0;\n // Retry until the router is available or max retries reached\n const interval = setInterval(() => {\n if (trySubscribe() || retryCount >= MAX_RETRIES) {\n if (retryCount >= MAX_RETRIES) {\n DEBUG_BUILD && debug.warn('Unable to instrument React Router: router not found after hydration.');\n }\n clearInterval(interval);\n }\n retryCount++;\n }, 50);\n }\n}\n\nfunction maybeCreateNavigationTransaction(name: string, url: string, source: 'url' | 'route'): Span | undefined {\n const client = getClient();\n\n if (!client) {\n return undefined;\n }\n\n return startBrowserTracingNavigationSpan(\n client,\n {\n // With span streaming, span names have to be low cardinality, so we can't fall back to the URL.\n // The route is resolved once the router settles, which updates the span name then.\n name: source === 'route' || !hasSpanStreamingEnabled(client) ? name : NAVIGATION_SPAN_NAME_FALLBACK,\n attributes: {\n [SENTRY_SEGMENT_NAME_SOURCE]: source,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router',\n ...(source === 'route' ? { [URL_TEMPLATE]: name } : {}),\n },\n },\n { url },\n );\n}\n\nfunction getActiveRootSpan(): Span | undefined {\n const activeSpan = getActiveSpan();\n if (!activeSpan) {\n return undefined;\n }\n\n const rootSpan = getRootSpan(activeSpan);\n\n const op = spanToJSON(rootSpan).attributes[SENTRY_OP];\n\n // Only use this root span if it is a pageload or navigation span\n return op === 'navigation' || op === 'pageload' ? rootSpan : undefined;\n}\n"],"names":["GLOBAL_OBJ","spanToJSON","URL_PATH","normalizePathname","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","updateSpanWithParameterizedRoute","isClientInstrumentationApiUsed","getAbsoluteUrl","isThenable","finalizeNavigationSpanFromRouterState","resolveNavigateArg","resolveNavigateAbsoluteUrl","SENTRY_OP","SENTRY_SEGMENT_NAME_SOURCE","DEBUG_BUILD","debug","getClient","startBrowserTracingNavigationSpan","hasSpanStreamingEnabled","NAVIGATION_SPAN_NAME_FALLBACK","SEMANTIC_ATTRIBUTE_SENTRY_OP","getActiveSpan","getRootSpan"],"mappings":"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"}
1
+ {"version":3,"file":"hydratedRouter.js","sources":["../../../src/client/hydratedRouter.ts"],"sourcesContent":["import { getAbsoluteUrl, startBrowserTracingNavigationSpan } from '@sentry/browser';\nimport type { Span } from '@sentry/core';\nimport {\n debug,\n getActiveSpan,\n getClient,\n getRootSpan,\n GLOBAL_OBJ,\n hasSpanStreamingEnabled,\n isThenable,\n NAVIGATION_SPAN_NAME_FALLBACK,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n spanToJSON,\n} from '@sentry/core';\nimport type { DataRouter } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport { isClientInstrumentationApiUsed } from './createClientInstrumentation';\nimport {\n finalizeNavigationSpanFromRouterState,\n normalizePathname,\n resolveNavigateAbsoluteUrl,\n resolveNavigateArg,\n updateSpanWithParameterizedRoute,\n} from './utils';\nimport { SENTRY_SEGMENT_NAME_SOURCE, SENTRY_OP, URL_PATH, URL_TEMPLATE } from '@sentry/conventions/attributes';\nimport { NAVIGATION } from '@sentry/conventions/op';\n\nconst GLOBAL_OBJ_WITH_DATA_ROUTER = GLOBAL_OBJ as typeof GLOBAL_OBJ & {\n __reactRouterDataRouter?: DataRouter;\n};\n\nconst WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window;\n\nconst MAX_RETRIES = 40; // 2 seconds at 50ms interval\n\n/**\n * Instruments the React Router Data Router for pageloads and navigation.\n *\n * This function waits for the router to be available after hydration, then:\n * 1. Updates the pageload transaction with parameterized route info\n * 2. Patches router.navigate() to create navigation transactions\n * 3. Subscribes to router state changes to update navigation transactions with parameterized routes\n */\nexport function instrumentHydratedRouter(): void {\n function trySubscribe(): boolean {\n const router = GLOBAL_OBJ_WITH_DATA_ROUTER.__reactRouterDataRouter;\n\n if (router) {\n // The first time we hit the router, we try to update the pageload transaction\n const pageloadSpan = getActiveRootSpan();\n\n if (pageloadSpan) {\n // Matched against `url.path` rather than the span name: with span streaming, the pageload\n // span is named `Pageload` until a route is resolved, so the name may not hold the pathname.\n const pageloadPath = spanToJSON(pageloadSpan).attributes[URL_PATH];\n if (\n typeof pageloadPath === 'string' &&\n // this event is for the currently active pageload\n normalizePathname(router.state.location.pathname) === normalizePathname(pageloadPath)\n ) {\n pageloadSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.pageload.react_router');\n updateSpanWithParameterizedRoute(pageloadSpan, router.state);\n }\n }\n\n // Patching navigate for creating accurate navigation transactions\n if (typeof router.navigate === 'function') {\n const originalNav = router.navigate.bind(router);\n router.navigate = function sentryPatchedNavigate(...args) {\n // Skip if instrumentation API is enabled (it handles navigation spans itself)\n if (!isClientInstrumentationApiUsed()) {\n const target = args[0];\n\n if (typeof target === 'number') {\n // navigate(0) triggers a reload, not a route change — skip span creation\n if (target !== 0) {\n const currentPathname = WINDOW.location?.pathname || '/';\n const navigationSpan = maybeCreateNavigationTransaction(\n currentPathname,\n getAbsoluteUrl(currentPathname),\n 'url',\n );\n\n const result = originalNav(...args);\n\n // Numeric navigations (`navigate(-1)`/`navigate(1)`) don't carry a destination\n // path, so we can only resolve the real URL/route once the router has settled.\n if (navigationSpan) {\n // Finalize from the (updated) router state after navigation completes, in both\n // the resolve and reject paths, so a rejected navigation still ends up with the\n // correct URL attributes instead of the placeholder start pathname.\n if (isThenable(result)) {\n result.then(\n () => finalizeNavigationSpanFromRouterState(navigationSpan, router.state),\n () => finalizeNavigationSpanFromRouterState(navigationSpan, router.state),\n );\n } else {\n finalizeNavigationSpanFromRouterState(navigationSpan, router.state);\n }\n }\n\n return result;\n }\n } else {\n maybeCreateNavigationTransaction(\n resolveNavigateArg(target) || '<unknown route>',\n resolveNavigateAbsoluteUrl(target),\n 'url',\n );\n }\n }\n return originalNav(...args);\n };\n }\n\n // Subscribe to router state changes to update navigation transactions (and any pageload\n // whose route info only became available after `trySubscribe`, e.g. lazy routes) with the\n // parameterized route.\n router.subscribe(newState => {\n const rootSpan = getActiveRootSpan();\n\n if (!rootSpan) {\n return;\n }\n\n const rootSpanJson = spanToJSON(rootSpan);\n const rootSpanAttributes = rootSpanJson.attributes;\n\n // When the instrumentation API is active, navigation roots are parameterized\n // by the native route hooks\n if (\n rootSpanAttributes[SENTRY_OP] === 'navigation' &&\n isClientInstrumentationApiUsed() &&\n rootSpanAttributes[SENTRY_SEGMENT_NAME_SOURCE] === 'route'\n ) {\n return;\n }\n\n const rootSpanName = rootSpanJson.name;\n const spanPathname = rootSpanAttributes[URL_PATH] as string | undefined;\n const destinationPathname = normalizePathname(newState.location.pathname);\n\n if (\n rootSpanName &&\n newState.navigation.state === 'idle' && // navigation has completed\n // this event is for the currently active root span\n (destinationPathname === normalizePathname(rootSpanName) ||\n (spanPathname && destinationPathname === normalizePathname(spanPathname)))\n ) {\n updateSpanWithParameterizedRoute(rootSpan, newState);\n }\n });\n return true;\n }\n return false;\n }\n\n // Wait until the router is available (since the SDK loads before hydration)\n if (!trySubscribe()) {\n let retryCount = 0;\n // Retry until the router is available or max retries reached\n const interval = setInterval(() => {\n if (trySubscribe() || retryCount >= MAX_RETRIES) {\n if (retryCount >= MAX_RETRIES) {\n DEBUG_BUILD && debug.warn('Unable to instrument React Router: router not found after hydration.');\n }\n clearInterval(interval);\n }\n retryCount++;\n }, 50);\n }\n}\n\nfunction maybeCreateNavigationTransaction(name: string, url: string, source: 'url' | 'route'): Span | undefined {\n const client = getClient();\n\n if (!client) {\n return undefined;\n }\n\n return startBrowserTracingNavigationSpan(\n client,\n {\n // With span streaming, span names have to be low cardinality, so we can't fall back to the URL.\n // The route is resolved once the router settles, which updates the span name then.\n name: source === 'route' || !hasSpanStreamingEnabled(client) ? name : NAVIGATION_SPAN_NAME_FALLBACK,\n attributes: {\n [SENTRY_SEGMENT_NAME_SOURCE]: source,\n [SENTRY_OP]: NAVIGATION,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router',\n ...(source === 'route' ? { [URL_TEMPLATE]: name } : {}),\n },\n },\n { url },\n );\n}\n\nfunction getActiveRootSpan(): Span | undefined {\n const activeSpan = getActiveSpan();\n if (!activeSpan) {\n return undefined;\n }\n\n const rootSpan = getRootSpan(activeSpan);\n\n const op = spanToJSON(rootSpan).attributes[SENTRY_OP];\n\n // Only use this root span if it is a pageload or navigation span\n return op === 'navigation' || op === 'pageload' ? rootSpan : undefined;\n}\n"],"names":["GLOBAL_OBJ","spanToJSON","URL_PATH","normalizePathname","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","updateSpanWithParameterizedRoute","isClientInstrumentationApiUsed","getAbsoluteUrl","isThenable","finalizeNavigationSpanFromRouterState","resolveNavigateArg","resolveNavigateAbsoluteUrl","SENTRY_OP","SENTRY_SEGMENT_NAME_SOURCE","DEBUG_BUILD","debug","getClient","startBrowserTracingNavigationSpan","hasSpanStreamingEnabled","NAVIGATION_SPAN_NAME_FALLBACK","NAVIGATION","getActiveSpan","getRootSpan"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const core = require('@sentry/core');
4
+ const server = require('@sentry/core/server');
4
5
 
5
6
  function createSentryHandleError({ logErrors = false }) {
6
7
  const handleError = async function handleError2(error, args) {
@@ -15,7 +16,7 @@ function createSentryHandleError({ logErrors = false }) {
15
16
  console.error(error);
16
17
  }
17
18
  try {
18
- await core.flushIfServerless();
19
+ await server.flushIfServerless();
19
20
  } catch {
20
21
  }
21
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"createSentryHandleError.js","sources":["../../../src/server/createSentryHandleError.ts"],"sourcesContent":["import { captureException, flushIfServerless } from '@sentry/core';\nimport type { HandleErrorFunction } from 'react-router';\n\nexport type SentryHandleErrorOptions = {\n logErrors?: boolean;\n};\n\n/**\n * A complete Sentry-instrumented handleError implementation that handles error reporting\n *\n * @returns A Sentry-instrumented handleError function\n */\nexport function createSentryHandleError({ logErrors = false }: SentryHandleErrorOptions): HandleErrorFunction {\n const handleError: HandleErrorFunction = async function handleError(error, args): Promise<void> {\n // React Router may abort some interrupted requests, don't report those\n if (!args.request.signal.aborted) {\n captureException(error, {\n mechanism: {\n type: 'react-router',\n handled: false,\n },\n });\n if (logErrors) {\n // eslint-disable-next-line no-console\n console.error(error);\n }\n try {\n await flushIfServerless();\n } catch {\n // Ignore flush errors to ensure error handling completes gracefully\n }\n }\n };\n\n return handleError;\n}\n"],"names":["handleError","captureException","flushIfServerless"],"mappings":";;;;AAYO,SAAS,uBAAA,CAAwB,EAAE,SAAA,GAAY,KAAA,EAAM,EAAkD;AAC5G,EAAA,MAAM,WAAA,GAAmC,eAAeA,YAAAA,CAAY,KAAA,EAAO,IAAA,EAAqB;AAE9F,IAAA,IAAI,CAAC,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,OAAA,EAAS;AAChC,MAAAC,qBAAA,CAAiB,KAAA,EAAO;AAAA,QACtB,SAAA,EAAW;AAAA,UACT,IAAA,EAAM,cAAA;AAAA,UACN,OAAA,EAAS;AAAA;AACX,OACD,CAAA;AACD,MAAA,IAAI,SAAA,EAAW;AAEb,QAAA,OAAA,CAAQ,MAAM,KAAK,CAAA;AAAA,MACrB;AACA,MAAA,IAAI;AACF,QAAA,MAAMC,sBAAA,EAAkB;AAAA,MAC1B,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,CAAA;AAEA,EAAA,OAAO,WAAA;AACT;;;;"}
1
+ {"version":3,"file":"createSentryHandleError.js","sources":["../../../src/server/createSentryHandleError.ts"],"sourcesContent":["import { captureException } from '@sentry/core';\nimport { flushIfServerless } from '@sentry/core/server';\nimport type { HandleErrorFunction } from 'react-router';\n\nexport type SentryHandleErrorOptions = {\n logErrors?: boolean;\n};\n\n/**\n * A complete Sentry-instrumented handleError implementation that handles error reporting\n *\n * @returns A Sentry-instrumented handleError function\n */\nexport function createSentryHandleError({ logErrors = false }: SentryHandleErrorOptions): HandleErrorFunction {\n const handleError: HandleErrorFunction = async function handleError(error, args): Promise<void> {\n // React Router may abort some interrupted requests, don't report those\n if (!args.request.signal.aborted) {\n captureException(error, {\n mechanism: {\n type: 'react-router',\n handled: false,\n },\n });\n if (logErrors) {\n // eslint-disable-next-line no-console\n console.error(error);\n }\n try {\n await flushIfServerless();\n } catch {\n // Ignore flush errors to ensure error handling completes gracefully\n }\n }\n };\n\n return handleError;\n}\n"],"names":["handleError","captureException","flushIfServerless"],"mappings":";;;;;AAaO,SAAS,uBAAA,CAAwB,EAAE,SAAA,GAAY,KAAA,EAAM,EAAkD;AAC5G,EAAA,MAAM,WAAA,GAAmC,eAAeA,YAAAA,CAAY,KAAA,EAAO,IAAA,EAAqB;AAE9F,IAAA,IAAI,CAAC,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,OAAA,EAAS;AAChC,MAAAC,qBAAA,CAAiB,KAAA,EAAO;AAAA,QACtB,SAAA,EAAW;AAAA,UACT,IAAA,EAAM,cAAA;AAAA,UACN,OAAA,EAAS;AAAA;AACX,OACD,CAAA;AACD,MAAA,IAAI,SAAA,EAAW;AAEb,QAAA,OAAA,CAAQ,MAAM,KAAK,CAAA;AAAA,MACrB;AACA,MAAA,IAAI;AACF,QAAA,MAAMC,wBAAA,EAAkB;AAAA,MAC1B,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,CAAA;AAEA,EAAA,OAAO,WAAA;AACT;;;;"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3
3
  const attributes = require('@sentry/conventions/attributes');
4
4
  const op = require('@sentry/conventions/op');
5
5
  const core = require('@sentry/core');
6
+ const server = require('@sentry/core/server');
6
7
  const debugBuild = require('../common/debug-build.js');
7
8
  const utils = require('../common/utils.js');
8
9
  const serverBuild = require('./serverBuild.js');
@@ -25,7 +26,7 @@ function createSentryServerInstrumentation(options = {}) {
25
26
  if (existingRootSpan) {
26
27
  core.updateSpanName(existingRootSpan, unparameterizedName);
27
28
  existingRootSpan.setAttributes({
28
- [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: "http.server",
29
+ [attributes.SENTRY_OP]: op.HTTP_SERVER,
29
30
  [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.http.react_router.instrumentation_api",
30
31
  [attributes.SENTRY_SEGMENT_NAME_SOURCE]: "url",
31
32
  [attributes.URL_FULL]: core.filterCollectedUrl(info.request.url),
@@ -41,15 +42,14 @@ function createSentryServerInstrumentation(options = {}) {
41
42
  });
42
43
  }
43
44
  } finally {
44
- await core.flushIfServerless();
45
+ await server.flushIfServerless();
45
46
  }
46
47
  } else {
47
48
  await core.startSpan(
48
49
  {
49
50
  name: unparameterizedName,
50
- forceTransaction: true,
51
51
  attributes: {
52
- [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: "http.server",
52
+ [attributes.SENTRY_OP]: op.HTTP_SERVER,
53
53
  [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.http.react_router.instrumentation_api",
54
54
  [attributes.SENTRY_SEGMENT_NAME_SOURCE]: "url",
55
55
  [attributes.HTTP_REQUEST_METHOD]: info.request.method,
@@ -68,7 +68,7 @@ function createSentryServerInstrumentation(options = {}) {
68
68
  });
69
69
  }
70
70
  } finally {
71
- await core.flushIfServerless();
71
+ await server.flushIfServerless();
72
72
  }
73
73
  }
74
74
  );
@@ -1 +1 @@
1
- {"version":3,"file":"createServerInstrumentation.js","sources":["../../../src/server/createServerInstrumentation.ts"],"sourcesContent":["import {\n SENTRY_SEGMENT_NAME_SOURCE,\n CODE_FUNCTION_NAME,\n HTTP_REQUEST_METHOD,\n HTTP_ROUTE,\n SENTRY_OP,\n URL_FULL,\n URL_PATH,\n} from '@sentry/conventions/attributes';\nimport { FUNCTION, MIDDLEWARE } from '@sentry/conventions/op';\nimport {\n debug,\n flushIfServerless,\n getActiveSpan,\n getClient,\n getCurrentScope,\n getRootSpan,\n hasSpanStreamingEnabled,\n HTTP_SPAN_NAME_FALLBACK,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SPAN_STATUS_ERROR,\n startSpan,\n updateSpanName,\n filterCollectedUrl,\n} from '@sentry/core';\nimport type { ServerInstrumentation } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport { captureInstrumentationError, getPathFromRequest, getPattern, normalizeRoutePath } from '../common/utils';\nimport { getMiddlewareName } from './serverBuild';\nimport { markInstrumentationApiUsed } from './serverGlobals';\n\n// Per-request middleware counters, keyed by the request's root span (the one transaction all of a\n// request's middlewares run under). The root span is the same instance across those middleware hooks\n// whether or not a Sentry OpenTelemetry tracer provider is set up, unlike the OTel context the counter\n// used to live on (which does not propagate without a provider).\nconst middlewareCountersByRootSpan = new WeakMap<object, Record<string, number>>();\n\n// Re-export for backward compatibility and external use\nexport { isInstrumentationApiUsed } from './serverGlobals';\n\n/**\n * Options for creating Sentry server instrumentation.\n */\nexport interface CreateSentryServerInstrumentationOptions {\n /**\n * Whether to capture errors from loaders/actions automatically.\n * @default true\n */\n captureErrors?: boolean;\n}\n\n/**\n * Creates a Sentry server instrumentation for React Router's instrumentation API.\n */\nexport function createSentryServerInstrumentation(\n options: CreateSentryServerInstrumentationOptions = {},\n): ServerInstrumentation {\n const { captureErrors = true } = options;\n\n DEBUG_BUILD && debug.log('React Router server instrumentation created.');\n\n return {\n handler(handler) {\n // Mark the instrumentation API active only when React Router actually invokes this\n markInstrumentationApiUsed();\n handler.instrument({\n async request(handleRequest, info) {\n const pathname = getPathFromRequest(info.request);\n const activeSpan = getActiveSpan();\n const existingRootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;\n\n const client = getClient();\n // With span streaming, span names have to be low cardinality, so we can't fall back to the URL\n // path. `updateRootSpanWithRoute` renames the span once React Router matches a route.\n const unparameterizedName =\n client && hasSpanStreamingEnabled(client)\n ? info.request.method?.toUpperCase() || HTTP_SPAN_NAME_FALLBACK\n : `${info.request.method} ${pathname}`;\n\n if (existingRootSpan) {\n updateSpanName(existingRootSpan, unparameterizedName);\n existingRootSpan.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.server',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.instrumentation_api',\n [SENTRY_SEGMENT_NAME_SOURCE]: 'url',\n [URL_FULL]: filterCollectedUrl(info.request.url),\n [URL_PATH]: pathname,\n });\n\n try {\n const result = await handleRequest();\n if (result.status === 'error' && result.error instanceof Error) {\n existingRootSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.request_handler', {\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_FULL]: pathname,\n });\n }\n } finally {\n await flushIfServerless();\n }\n } else {\n await startSpan(\n {\n name: unparameterizedName,\n forceTransaction: true,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.server',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.instrumentation_api',\n [SENTRY_SEGMENT_NAME_SOURCE]: 'url',\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_PATH]: pathname,\n [URL_FULL]: filterCollectedUrl(info.request.url),\n },\n },\n async span => {\n try {\n const result = await handleRequest();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.request_handler', {\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_FULL]: pathname,\n });\n }\n } finally {\n await flushIfServerless();\n }\n },\n );\n }\n },\n });\n },\n\n route(route) {\n // Also mark active here, in case route registration runs (mirrors the handler callback above).\n markInstrumentationApiUsed();\n const routeId = route.id;\n\n route.instrument({\n async loader(callLoader, info) {\n const urlPath = getPathFromRequest(info.request);\n const pattern = getPattern(info);\n const routePattern = normalizeRoutePath(pattern) || urlPath;\n updateRootSpanWithRoute(info.request.method, pattern, urlPath);\n\n await startSpan(\n {\n name: routePattern,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'loader',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callLoader();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.loader', {\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async action(callAction, info) {\n const urlPath = getPathFromRequest(info.request);\n const pattern = getPattern(info);\n const routePattern = normalizeRoutePath(pattern) || urlPath;\n updateRootSpanWithRoute(info.request.method, pattern, urlPath);\n\n await startSpan(\n {\n name: routePattern,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'action',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callAction();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.action', {\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async middleware(callMiddleware, info) {\n const urlPath = getPathFromRequest(info.request);\n const pattern = getPattern(info);\n const routePattern = normalizeRoutePath(pattern) || urlPath;\n\n updateRootSpanWithRoute(info.request.method, pattern, urlPath);\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;\n let middlewareIndex = 0;\n if (rootSpan) {\n let counters = middlewareCountersByRootSpan.get(rootSpan);\n if (!counters) {\n counters = {};\n middlewareCountersByRootSpan.set(rootSpan, counters);\n }\n middlewareIndex = counters[routeId] ?? 0;\n counters[routeId] = middlewareIndex + 1;\n }\n\n const middlewareName = getMiddlewareName(routeId, middlewareIndex);\n\n await startSpan(\n {\n name: `middleware ${middlewareName || routeId}`,\n attributes: {\n [SENTRY_OP]: MIDDLEWARE,\n [CODE_FUNCTION_NAME]: 'middleware',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n 'react_router.route.id': routeId,\n [HTTP_ROUTE]: routePattern,\n ...(middlewareName && { 'react_router.middleware.name': middlewareName }),\n 'react_router.middleware.index': middlewareIndex,\n },\n },\n async span => {\n const result = await callMiddleware();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.middleware', {\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async lazy(callLazy) {\n await startSpan(\n {\n name: 'Lazy Route Load',\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'lazy',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callLazy();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.lazy', {});\n }\n },\n );\n },\n });\n },\n };\n}\n\nfunction updateRootSpanWithRoute(method: string, pattern: string | undefined, urlPath: string): void {\n const activeSpan = getActiveSpan();\n if (!activeSpan) return;\n const rootSpan = getRootSpan(activeSpan);\n if (!rootSpan) return;\n\n // Skip update if URL path is invalid (failed to parse)\n if (!urlPath || urlPath === '<unknown>') {\n DEBUG_BUILD && debug.warn('Cannot update span with invalid URL path:', urlPath);\n return;\n }\n\n const hasPattern = !!pattern;\n const routeName = hasPattern ? normalizeRoutePath(pattern) || urlPath : urlPath;\n\n const transactionName = `${method} ${routeName}`;\n\n const client = getClient();\n // With span streaming, span names have to be low cardinality, so we can't fall back to the URL path.\n const isUnparameterizedStreamedSpan = !hasPattern && !!client && hasSpanStreamingEnabled(client);\n updateSpanName(\n rootSpan,\n isUnparameterizedStreamedSpan ? method.toUpperCase() || HTTP_SPAN_NAME_FALLBACK : transactionName,\n );\n rootSpan.setAttributes({\n [HTTP_ROUTE]: routeName,\n [SENTRY_SEGMENT_NAME_SOURCE]: hasPattern ? 'route' : 'url',\n });\n\n // Also update the scope's transaction name so errors captured during this request\n // have the correct transaction name (not the initial placeholder like \"GET *\")\n getCurrentScope().setTransactionName(transactionName);\n}\n"],"names":["DEBUG_BUILD","debug","markInstrumentationApiUsed","getPathFromRequest","getActiveSpan","getRootSpan","getClient","hasSpanStreamingEnabled","HTTP_SPAN_NAME_FALLBACK","updateSpanName","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SENTRY_SEGMENT_NAME_SOURCE","URL_FULL","filterCollectedUrl","URL_PATH","SPAN_STATUS_ERROR","captureInstrumentationError","HTTP_REQUEST_METHOD","flushIfServerless","startSpan","getPattern","normalizeRoutePath","SENTRY_OP","FUNCTION","CODE_FUNCTION_NAME","getMiddlewareName","MIDDLEWARE","HTTP_ROUTE","getCurrentScope"],"mappings":"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"}
1
+ {"version":3,"file":"createServerInstrumentation.js","sources":["../../../src/server/createServerInstrumentation.ts"],"sourcesContent":["import {\n SENTRY_SEGMENT_NAME_SOURCE,\n CODE_FUNCTION_NAME,\n HTTP_REQUEST_METHOD,\n HTTP_ROUTE,\n SENTRY_OP,\n URL_FULL,\n URL_PATH,\n} from '@sentry/conventions/attributes';\nimport { FUNCTION, HTTP_SERVER, MIDDLEWARE } from '@sentry/conventions/op';\nimport {\n debug,\n getActiveSpan,\n getClient,\n getCurrentScope,\n getRootSpan,\n hasSpanStreamingEnabled,\n HTTP_SPAN_NAME_FALLBACK,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SPAN_STATUS_ERROR,\n startSpan,\n updateSpanName,\n filterCollectedUrl,\n} from '@sentry/core';\nimport { flushIfServerless } from '@sentry/core/server';\nimport type { ServerInstrumentation } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport { captureInstrumentationError, getPathFromRequest, getPattern, normalizeRoutePath } from '../common/utils';\nimport { getMiddlewareName } from './serverBuild';\nimport { markInstrumentationApiUsed } from './serverGlobals';\n\n// Per-request middleware counters, keyed by the request's root span (the one transaction all of a\n// request's middlewares run under). The root span is the same instance across those middleware hooks\n// whether or not a Sentry OpenTelemetry tracer provider is set up, unlike the OTel context the counter\n// used to live on (which does not propagate without a provider).\nconst middlewareCountersByRootSpan = new WeakMap<object, Record<string, number>>();\n\n// Re-export for backward compatibility and external use\nexport { isInstrumentationApiUsed } from './serverGlobals';\n\n/**\n * Options for creating Sentry server instrumentation.\n */\nexport interface CreateSentryServerInstrumentationOptions {\n /**\n * Whether to capture errors from loaders/actions automatically.\n * @default true\n */\n captureErrors?: boolean;\n}\n\n/**\n * Creates a Sentry server instrumentation for React Router's instrumentation API.\n */\nexport function createSentryServerInstrumentation(\n options: CreateSentryServerInstrumentationOptions = {},\n): ServerInstrumentation {\n const { captureErrors = true } = options;\n\n DEBUG_BUILD && debug.log('React Router server instrumentation created.');\n\n return {\n handler(handler) {\n // Mark the instrumentation API active only when React Router actually invokes this\n markInstrumentationApiUsed();\n handler.instrument({\n async request(handleRequest, info) {\n const pathname = getPathFromRequest(info.request);\n const activeSpan = getActiveSpan();\n const existingRootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;\n\n const client = getClient();\n // With span streaming, span names have to be low cardinality, so we can't fall back to the URL\n // path. `updateRootSpanWithRoute` renames the span once React Router matches a route.\n const unparameterizedName =\n client && hasSpanStreamingEnabled(client)\n ? info.request.method?.toUpperCase() || HTTP_SPAN_NAME_FALLBACK\n : `${info.request.method} ${pathname}`;\n\n if (existingRootSpan) {\n updateSpanName(existingRootSpan, unparameterizedName);\n existingRootSpan.setAttributes({\n [SENTRY_OP]: HTTP_SERVER,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.instrumentation_api',\n [SENTRY_SEGMENT_NAME_SOURCE]: 'url',\n [URL_FULL]: filterCollectedUrl(info.request.url),\n [URL_PATH]: pathname,\n });\n\n try {\n const result = await handleRequest();\n if (result.status === 'error' && result.error instanceof Error) {\n existingRootSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.request_handler', {\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_FULL]: pathname,\n });\n }\n } finally {\n await flushIfServerless();\n }\n } else {\n await startSpan(\n {\n name: unparameterizedName,\n attributes: {\n [SENTRY_OP]: HTTP_SERVER,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.instrumentation_api',\n [SENTRY_SEGMENT_NAME_SOURCE]: 'url',\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_PATH]: pathname,\n [URL_FULL]: filterCollectedUrl(info.request.url),\n },\n },\n async span => {\n try {\n const result = await handleRequest();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.request_handler', {\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_FULL]: pathname,\n });\n }\n } finally {\n await flushIfServerless();\n }\n },\n );\n }\n },\n });\n },\n\n route(route) {\n // Also mark active here, in case route registration runs (mirrors the handler callback above).\n markInstrumentationApiUsed();\n const routeId = route.id;\n\n route.instrument({\n async loader(callLoader, info) {\n const urlPath = getPathFromRequest(info.request);\n const pattern = getPattern(info);\n const routePattern = normalizeRoutePath(pattern) || urlPath;\n updateRootSpanWithRoute(info.request.method, pattern, urlPath);\n\n await startSpan(\n {\n name: routePattern,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'loader',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callLoader();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.loader', {\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async action(callAction, info) {\n const urlPath = getPathFromRequest(info.request);\n const pattern = getPattern(info);\n const routePattern = normalizeRoutePath(pattern) || urlPath;\n updateRootSpanWithRoute(info.request.method, pattern, urlPath);\n\n await startSpan(\n {\n name: routePattern,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'action',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callAction();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.action', {\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async middleware(callMiddleware, info) {\n const urlPath = getPathFromRequest(info.request);\n const pattern = getPattern(info);\n const routePattern = normalizeRoutePath(pattern) || urlPath;\n\n updateRootSpanWithRoute(info.request.method, pattern, urlPath);\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;\n let middlewareIndex = 0;\n if (rootSpan) {\n let counters = middlewareCountersByRootSpan.get(rootSpan);\n if (!counters) {\n counters = {};\n middlewareCountersByRootSpan.set(rootSpan, counters);\n }\n middlewareIndex = counters[routeId] ?? 0;\n counters[routeId] = middlewareIndex + 1;\n }\n\n const middlewareName = getMiddlewareName(routeId, middlewareIndex);\n\n await startSpan(\n {\n name: `middleware ${middlewareName || routeId}`,\n attributes: {\n [SENTRY_OP]: MIDDLEWARE,\n [CODE_FUNCTION_NAME]: 'middleware',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n 'react_router.route.id': routeId,\n [HTTP_ROUTE]: routePattern,\n ...(middlewareName && { 'react_router.middleware.name': middlewareName }),\n 'react_router.middleware.index': middlewareIndex,\n },\n },\n async span => {\n const result = await callMiddleware();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.middleware', {\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async lazy(callLazy) {\n await startSpan(\n {\n name: 'Lazy Route Load',\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'lazy',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callLazy();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.lazy', {});\n }\n },\n );\n },\n });\n },\n };\n}\n\nfunction updateRootSpanWithRoute(method: string, pattern: string | undefined, urlPath: string): void {\n const activeSpan = getActiveSpan();\n if (!activeSpan) return;\n const rootSpan = getRootSpan(activeSpan);\n if (!rootSpan) return;\n\n // Skip update if URL path is invalid (failed to parse)\n if (!urlPath || urlPath === '<unknown>') {\n DEBUG_BUILD && debug.warn('Cannot update span with invalid URL path:', urlPath);\n return;\n }\n\n const hasPattern = !!pattern;\n const routeName = hasPattern ? normalizeRoutePath(pattern) || urlPath : urlPath;\n\n const transactionName = `${method} ${routeName}`;\n\n const client = getClient();\n // With span streaming, span names have to be low cardinality, so we can't fall back to the URL path.\n const isUnparameterizedStreamedSpan = !hasPattern && !!client && hasSpanStreamingEnabled(client);\n updateSpanName(\n rootSpan,\n isUnparameterizedStreamedSpan ? method.toUpperCase() || HTTP_SPAN_NAME_FALLBACK : transactionName,\n );\n rootSpan.setAttributes({\n [HTTP_ROUTE]: routeName,\n [SENTRY_SEGMENT_NAME_SOURCE]: hasPattern ? 'route' : 'url',\n });\n\n // Also update the scope's transaction name so errors captured during this request\n // have the correct transaction name (not the initial placeholder like \"GET *\")\n getCurrentScope().setTransactionName(transactionName);\n}\n"],"names":["DEBUG_BUILD","debug","markInstrumentationApiUsed","getPathFromRequest","getActiveSpan","getRootSpan","getClient","hasSpanStreamingEnabled","HTTP_SPAN_NAME_FALLBACK","updateSpanName","SENTRY_OP","HTTP_SERVER","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SENTRY_SEGMENT_NAME_SOURCE","URL_FULL","filterCollectedUrl","URL_PATH","SPAN_STATUS_ERROR","captureInstrumentationError","HTTP_REQUEST_METHOD","flushIfServerless","startSpan","getPattern","normalizeRoutePath","FUNCTION","CODE_FUNCTION_NAME","getMiddlewareName","MIDDLEWARE","HTTP_ROUTE","getCurrentScope"],"mappings":"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"}
@@ -2,6 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const attributes = require('@sentry/conventions/attributes');
4
4
  const core = require('@sentry/core');
5
+ const server = require('@sentry/core/server');
5
6
  const serverGlobals = require('./serverGlobals.js');
6
7
 
7
8
  function wrapSentryHandleRequest(originalHandle) {
@@ -46,7 +47,7 @@ function wrapSentryHandleRequest(originalHandle) {
46
47
  );
47
48
  }
48
49
  } finally {
49
- await core.flushIfServerless();
50
+ await server.flushIfServerless();
50
51
  }
51
52
  function isRouterContextProvider(ctx) {
52
53
  return typeof ctx?.get === "function";
@@ -1 +1 @@
1
- {"version":3,"file":"wrapSentryHandleRequest.js","sources":["../../../src/server/wrapSentryHandleRequest.ts"],"sourcesContent":["import { SENTRY_SEGMENT_NAME_SOURCE, HTTP_ROUTE } from '@sentry/conventions/attributes';\nimport {\n flushIfServerless,\n getActiveSpan,\n getCurrentScope,\n getRootSpan,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n updateSpanName,\n} from '@sentry/core';\nimport type { AppLoadContext, EntryContext, RouterContextProvider } from 'react-router';\nimport { isInstrumentationApiUsed } from './serverGlobals';\n\ntype OriginalHandleRequestWithoutMiddleware = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n) => Promise<unknown>;\n\ntype OriginalHandleRequestWithMiddleware = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: RouterContextProvider,\n) => Promise<unknown>;\n\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithoutMiddleware,\n): OriginalHandleRequestWithoutMiddleware;\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithMiddleware,\n): OriginalHandleRequestWithMiddleware;\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithoutMiddleware | OriginalHandleRequestWithMiddleware,\n): OriginalHandleRequestWithoutMiddleware | OriginalHandleRequestWithMiddleware {\n return async function sentryInstrumentedHandleRequest(\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext | RouterContextProvider,\n ) {\n const parameterizedPath =\n routerContext?.staticHandlerContext?.matches?.[routerContext.staticHandlerContext.matches.length - 1]?.route.path;\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;\n\n if (parameterizedPath && rootSpan) {\n // Normalize route name - avoid \"//\" for root routes\n const routeName = parameterizedPath.startsWith('/') ? parameterizedPath : `/${parameterizedPath}`;\n\n const transactionName = `${request.method} ${routeName}`;\n\n updateSpanName(rootSpan, transactionName);\n getCurrentScope().setTransactionName(transactionName);\n\n // Set route attributes - acts as fallback for lazy-only routes when using instrumentation API\n // Don't override origin when instrumentation API is used (preserve instrumentation_api origin)\n if (isInstrumentationApiUsed()) {\n rootSpan.setAttributes({\n [HTTP_ROUTE]: routeName,\n [SENTRY_SEGMENT_NAME_SOURCE]: 'route',\n });\n } else {\n rootSpan.setAttributes({\n [HTTP_ROUTE]: routeName,\n [SENTRY_SEGMENT_NAME_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.request_handler',\n });\n }\n }\n\n try {\n // Type guard to call the correct overload based on loadContext type\n if (isRouterContextProvider(loadContext)) {\n // loadContext is RouterContextProvider\n return await (originalHandle as OriginalHandleRequestWithMiddleware)(\n request,\n responseStatusCode,\n responseHeaders,\n routerContext,\n loadContext,\n );\n } else {\n // loadContext is AppLoadContext\n return await (originalHandle as OriginalHandleRequestWithoutMiddleware)(\n request,\n responseStatusCode,\n responseHeaders,\n routerContext,\n loadContext,\n );\n }\n } finally {\n await flushIfServerless();\n }\n\n /**\n * Helper type guard to determine if the context is a RouterContextProvider.\n *\n * @param ctx - The context to check\n * @returns True if the context is a RouterContextProvider\n */\n function isRouterContextProvider(ctx: AppLoadContext | RouterContextProvider): ctx is RouterContextProvider {\n return typeof (ctx as RouterContextProvider)?.get === 'function';\n }\n };\n}\n"],"names":["getActiveSpan","getRootSpan","updateSpanName","getCurrentScope","isInstrumentationApiUsed","HTTP_ROUTE","SENTRY_SEGMENT_NAME_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","flushIfServerless"],"mappings":";;;;;;AAoDO,SAAS,wBACd,cAAA,EAC8E;AAC9E,EAAA,OAAO,eAAe,+BAAA,CACpB,OAAA,EACA,kBAAA,EACA,eAAA,EACA,eACA,WAAA,EACA;AACA,IAAA,MAAM,iBAAA,GACJ,aAAA,EAAe,oBAAA,EAAsB,OAAA,GAAU,aAAA,CAAc,qBAAqB,OAAA,CAAQ,MAAA,GAAS,CAAC,CAAA,EAAG,KAAA,CAAM,IAAA;AAE/G,IAAA,MAAM,aAAaA,kBAAA,EAAc;AACjC,IAAA,MAAM,QAAA,GAAW,UAAA,GAAaC,gBAAA,CAAY,UAAU,CAAA,GAAI,MAAA;AAExD,IAAA,IAAI,qBAAqB,QAAA,EAAU;AAEjC,MAAA,MAAM,YAAY,iBAAA,CAAkB,UAAA,CAAW,GAAG,CAAA,GAAI,iBAAA,GAAoB,IAAI,iBAAiB,CAAA,CAAA;AAE/F,MAAA,MAAM,eAAA,GAAkB,CAAA,EAAG,OAAA,CAAQ,MAAM,IAAI,SAAS,CAAA,CAAA;AAEtD,MAAAC,mBAAA,CAAe,UAAU,eAAe,CAAA;AACxC,MAAAC,oBAAA,EAAgB,CAAE,mBAAmB,eAAe,CAAA;AAIpD,MAAA,IAAIC,wCAAyB,EAAG;AAC9B,QAAA,QAAA,CAAS,aAAA,CAAc;AAAA,UACrB,CAACC,qBAAU,GAAG,SAAA;AAAA,UACd,CAACC,qCAA0B,GAAG;AAAA,SAC/B,CAAA;AAAA,MACH,CAAA,MAAO;AACL,QAAA,QAAA,CAAS,aAAA,CAAc;AAAA,UACrB,CAACD,qBAAU,GAAG,SAAA;AAAA,UACd,CAACC,qCAA0B,GAAG,OAAA;AAAA,UAC9B,CAACC,qCAAgC,GAAG;AAAA,SACrC,CAAA;AAAA,MACH;AAAA,IACF;AAEA,IAAA,IAAI;AAEF,MAAA,IAAI,uBAAA,CAAwB,WAAW,CAAA,EAAG;AAExC,QAAA,OAAO,MAAO,cAAA;AAAA,UACZ,OAAA;AAAA,UACA,kBAAA;AAAA,UACA,eAAA;AAAA,UACA,aAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF,CAAA,MAAO;AAEL,QAAA,OAAO,MAAO,cAAA;AAAA,UACZ,OAAA;AAAA,UACA,kBAAA;AAAA,UACA,eAAA;AAAA,UACA,aAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF;AAAA,IACF,CAAA,SAAE;AACA,MAAA,MAAMC,sBAAA,EAAkB;AAAA,IAC1B;AAQA,IAAA,SAAS,wBAAwB,GAAA,EAA2E;AAC1G,MAAA,OAAO,OAAQ,KAA+B,GAAA,KAAQ,UAAA;AAAA,IACxD;AAAA,EACF,CAAA;AACF;;;;"}
1
+ {"version":3,"file":"wrapSentryHandleRequest.js","sources":["../../../src/server/wrapSentryHandleRequest.ts"],"sourcesContent":["import { SENTRY_SEGMENT_NAME_SOURCE, HTTP_ROUTE } from '@sentry/conventions/attributes';\nimport {\n getActiveSpan,\n getCurrentScope,\n getRootSpan,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n updateSpanName,\n} from '@sentry/core';\nimport { flushIfServerless } from '@sentry/core/server';\nimport type { AppLoadContext, EntryContext, RouterContextProvider } from 'react-router';\nimport { isInstrumentationApiUsed } from './serverGlobals';\n\ntype OriginalHandleRequestWithoutMiddleware = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n) => Promise<unknown>;\n\ntype OriginalHandleRequestWithMiddleware = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: RouterContextProvider,\n) => Promise<unknown>;\n\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithoutMiddleware,\n): OriginalHandleRequestWithoutMiddleware;\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithMiddleware,\n): OriginalHandleRequestWithMiddleware;\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithoutMiddleware | OriginalHandleRequestWithMiddleware,\n): OriginalHandleRequestWithoutMiddleware | OriginalHandleRequestWithMiddleware {\n return async function sentryInstrumentedHandleRequest(\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext | RouterContextProvider,\n ) {\n const parameterizedPath =\n routerContext?.staticHandlerContext?.matches?.[routerContext.staticHandlerContext.matches.length - 1]?.route.path;\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;\n\n if (parameterizedPath && rootSpan) {\n // Normalize route name - avoid \"//\" for root routes\n const routeName = parameterizedPath.startsWith('/') ? parameterizedPath : `/${parameterizedPath}`;\n\n const transactionName = `${request.method} ${routeName}`;\n\n updateSpanName(rootSpan, transactionName);\n getCurrentScope().setTransactionName(transactionName);\n\n // Set route attributes - acts as fallback for lazy-only routes when using instrumentation API\n // Don't override origin when instrumentation API is used (preserve instrumentation_api origin)\n if (isInstrumentationApiUsed()) {\n rootSpan.setAttributes({\n [HTTP_ROUTE]: routeName,\n [SENTRY_SEGMENT_NAME_SOURCE]: 'route',\n });\n } else {\n rootSpan.setAttributes({\n [HTTP_ROUTE]: routeName,\n [SENTRY_SEGMENT_NAME_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.request_handler',\n });\n }\n }\n\n try {\n // Type guard to call the correct overload based on loadContext type\n if (isRouterContextProvider(loadContext)) {\n // loadContext is RouterContextProvider\n return await (originalHandle as OriginalHandleRequestWithMiddleware)(\n request,\n responseStatusCode,\n responseHeaders,\n routerContext,\n loadContext,\n );\n } else {\n // loadContext is AppLoadContext\n return await (originalHandle as OriginalHandleRequestWithoutMiddleware)(\n request,\n responseStatusCode,\n responseHeaders,\n routerContext,\n loadContext,\n );\n }\n } finally {\n await flushIfServerless();\n }\n\n /**\n * Helper type guard to determine if the context is a RouterContextProvider.\n *\n * @param ctx - The context to check\n * @returns True if the context is a RouterContextProvider\n */\n function isRouterContextProvider(ctx: AppLoadContext | RouterContextProvider): ctx is RouterContextProvider {\n return typeof (ctx as RouterContextProvider)?.get === 'function';\n }\n };\n}\n"],"names":["getActiveSpan","getRootSpan","updateSpanName","getCurrentScope","isInstrumentationApiUsed","HTTP_ROUTE","SENTRY_SEGMENT_NAME_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","flushIfServerless"],"mappings":";;;;;;;AAoDO,SAAS,wBACd,cAAA,EAC8E;AAC9E,EAAA,OAAO,eAAe,+BAAA,CACpB,OAAA,EACA,kBAAA,EACA,eAAA,EACA,eACA,WAAA,EACA;AACA,IAAA,MAAM,iBAAA,GACJ,aAAA,EAAe,oBAAA,EAAsB,OAAA,GAAU,aAAA,CAAc,qBAAqB,OAAA,CAAQ,MAAA,GAAS,CAAC,CAAA,EAAG,KAAA,CAAM,IAAA;AAE/G,IAAA,MAAM,aAAaA,kBAAA,EAAc;AACjC,IAAA,MAAM,QAAA,GAAW,UAAA,GAAaC,gBAAA,CAAY,UAAU,CAAA,GAAI,MAAA;AAExD,IAAA,IAAI,qBAAqB,QAAA,EAAU;AAEjC,MAAA,MAAM,YAAY,iBAAA,CAAkB,UAAA,CAAW,GAAG,CAAA,GAAI,iBAAA,GAAoB,IAAI,iBAAiB,CAAA,CAAA;AAE/F,MAAA,MAAM,eAAA,GAAkB,CAAA,EAAG,OAAA,CAAQ,MAAM,IAAI,SAAS,CAAA,CAAA;AAEtD,MAAAC,mBAAA,CAAe,UAAU,eAAe,CAAA;AACxC,MAAAC,oBAAA,EAAgB,CAAE,mBAAmB,eAAe,CAAA;AAIpD,MAAA,IAAIC,wCAAyB,EAAG;AAC9B,QAAA,QAAA,CAAS,aAAA,CAAc;AAAA,UACrB,CAACC,qBAAU,GAAG,SAAA;AAAA,UACd,CAACC,qCAA0B,GAAG;AAAA,SAC/B,CAAA;AAAA,MACH,CAAA,MAAO;AACL,QAAA,QAAA,CAAS,aAAA,CAAc;AAAA,UACrB,CAACD,qBAAU,GAAG,SAAA;AAAA,UACd,CAACC,qCAA0B,GAAG,OAAA;AAAA,UAC9B,CAACC,qCAAgC,GAAG;AAAA,SACrC,CAAA;AAAA,MACH;AAAA,IACF;AAEA,IAAA,IAAI;AAEF,MAAA,IAAI,uBAAA,CAAwB,WAAW,CAAA,EAAG;AAExC,QAAA,OAAO,MAAO,cAAA;AAAA,UACZ,OAAA;AAAA,UACA,kBAAA;AAAA,UACA,eAAA;AAAA,UACA,aAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF,CAAA,MAAO;AAEL,QAAA,OAAO,MAAO,cAAA;AAAA,UACZ,OAAA;AAAA,UACA,kBAAA;AAAA,UACA,eAAA;AAAA,UACA,aAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF;AAAA,IACF,CAAA,SAAE;AACA,MAAA,MAAMC,wBAAA,EAAkB;AAAA,IAC1B;AAQA,IAAA,SAAS,wBAAwB,GAAA,EAA2E;AAC1G,MAAA,OAAO,OAAQ,KAA+B,GAAA,KAAQ,UAAA;AAAA,IACxD;AAAA,EACF,CAAA;AACF;;;;"}
@@ -1,11 +1,11 @@
1
1
  import { startBrowserTracingNavigationSpan, getAbsoluteUrl } from '@sentry/browser';
2
- import { debug, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_STATUS_ERROR, GLOBAL_OBJ, getClient, NAVIGATION_SPAN_NAME_FALLBACK, SEMANTIC_ATTRIBUTE_SENTRY_OP, hasSpanStreamingEnabled, filterCollectedUrl, getActiveSpan, getRootSpan, spanToJSON, updateSpanName } from '@sentry/core';
2
+ import { debug, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_STATUS_ERROR, GLOBAL_OBJ, getClient, NAVIGATION_SPAN_NAME_FALLBACK, hasSpanStreamingEnabled, filterCollectedUrl, getActiveSpan, getRootSpan, spanToJSON, updateSpanName } from '@sentry/core';
3
3
  import { startSpan } from '@sentry/core/browser';
4
4
  import { DEBUG_BUILD } from '../common/debug-build.js';
5
5
  import { captureInstrumentationError, getPathFromRequest, normalizeRoutePath, getPattern } from '../common/utils.js';
6
6
  import { updateNavigationSpanUrlFromLocation, finalizeNavigationSpanFromHydratedRouter, resolveNavigateArg, resolveNavigateAbsoluteUrl } from './utils.js';
7
7
  import { CODE_FUNCTION_NAME, SENTRY_OP, SENTRY_SEGMENT_NAME_SOURCE, URL_FULL, URL_TEMPLATE } from '@sentry/conventions/attributes';
8
- import { FUNCTION, MIDDLEWARE } from '@sentry/conventions/op';
8
+ import { FUNCTION, MIDDLEWARE, NAVIGATION } from '@sentry/conventions/op';
9
9
 
10
10
  const WINDOW = GLOBAL_OBJ;
11
11
  let currentNumericNavigationSpan;
@@ -45,7 +45,7 @@ function createSentryClientInstrumentation(options = {}) {
45
45
  name: hasSpanStreamingEnabled(client) ? NAVIGATION_SPAN_NAME_FALLBACK : pathname,
46
46
  attributes: {
47
47
  [SENTRY_SEGMENT_NAME_SOURCE]: "url",
48
- [SEMANTIC_ATTRIBUTE_SENTRY_OP]: "navigation",
48
+ [SENTRY_OP]: NAVIGATION,
49
49
  [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.navigation.react_router.instrumentation_api",
50
50
  "navigation.type": "browser.popstate"
51
51
  }
@@ -81,7 +81,7 @@ function createSentryClientInstrumentation(options = {}) {
81
81
  name: hasSpanStreamingEnabled(client2) ? NAVIGATION_SPAN_NAME_FALLBACK : currentPathname,
82
82
  attributes: {
83
83
  [SENTRY_SEGMENT_NAME_SOURCE]: "url",
84
- [SEMANTIC_ATTRIBUTE_SENTRY_OP]: "navigation",
84
+ [SENTRY_OP]: NAVIGATION,
85
85
  [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.navigation.react_router.instrumentation_api",
86
86
  "navigation.type": navigationType
87
87
  }
@@ -120,7 +120,7 @@ function createSentryClientInstrumentation(options = {}) {
120
120
  name: hasSpanStreamingEnabled(client) ? NAVIGATION_SPAN_NAME_FALLBACK : toPath,
121
121
  attributes: {
122
122
  [SENTRY_SEGMENT_NAME_SOURCE]: "url",
123
- [SEMANTIC_ATTRIBUTE_SENTRY_OP]: "navigation",
123
+ [SENTRY_OP]: NAVIGATION,
124
124
  [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.navigation.react_router.instrumentation_api",
125
125
  "navigation.type": "router.navigate"
126
126
  }
@@ -1 +1 @@
1
- {"version":3,"file":"createClientInstrumentation.js","sources":["../../../src/client/createClientInstrumentation.ts"],"sourcesContent":["// oxlint-disable max-lines\nimport { getAbsoluteUrl, startBrowserTracingNavigationSpan } from '@sentry/browser';\nimport type { Span } from '@sentry/core';\nimport {\n debug,\n getActiveSpan,\n getClient,\n getRootSpan,\n GLOBAL_OBJ,\n hasSpanStreamingEnabled,\n NAVIGATION_SPAN_NAME_FALLBACK,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n spanToJSON,\n SPAN_STATUS_ERROR,\n updateSpanName,\n filterCollectedUrl,\n} from '@sentry/core';\nimport { startSpan } from '@sentry/core/browser';\nimport type { ClientInstrumentation } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport { captureInstrumentationError, getPathFromRequest, getPattern, normalizeRoutePath } from '../common/utils';\nimport {\n resolveNavigateAbsoluteUrl,\n resolveNavigateArg,\n finalizeNavigationSpanFromHydratedRouter,\n updateNavigationSpanUrlFromLocation,\n} from './utils';\nimport {\n SENTRY_SEGMENT_NAME_SOURCE,\n CODE_FUNCTION_NAME,\n SENTRY_OP,\n URL_FULL,\n URL_TEMPLATE,\n} from '@sentry/conventions/attributes';\nimport { FUNCTION, MIDDLEWARE } from '@sentry/conventions/op';\n\nconst WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window;\n\n// Tracks active numeric navigation span to prevent duplicate spans when popstate fires\nlet currentNumericNavigationSpan: Span | undefined;\n\n// Per-request middleware counters, keyed by Request\nconst middlewareCountersMap = new WeakMap<object, Record<string, number>>();\n\nconst SENTRY_CLIENT_INSTRUMENTATION_FLAG = '__sentryReactRouterClientInstrumentationUsed';\n// Intentionally never reset - once set, instrumentation API handles all navigations for the session.\nconst SENTRY_NAVIGATE_HOOK_INVOKED_FLAG = '__sentryReactRouterNavigateHookInvoked';\nconst SENTRY_POPSTATE_LISTENER_ADDED_FLAG = '__sentryReactRouterPopstateListenerAdded';\n\ntype GlobalObjWithFlags = typeof GLOBAL_OBJ & {\n [SENTRY_CLIENT_INSTRUMENTATION_FLAG]?: boolean;\n [SENTRY_NAVIGATE_HOOK_INVOKED_FLAG]?: boolean;\n [SENTRY_POPSTATE_LISTENER_ADDED_FLAG]?: boolean;\n};\n\nconst GLOBAL_WITH_FLAGS = GLOBAL_OBJ as GlobalObjWithFlags;\n\n/**\n * Options for creating Sentry client instrumentation.\n */\nexport interface CreateSentryClientInstrumentationOptions {\n /**\n * Whether to capture errors from loaders/actions automatically.\n * Set to `false` to avoid duplicates if using custom error handlers.\n * @default true\n */\n captureErrors?: boolean;\n}\n\n/**\n * Creates a Sentry client instrumentation for React Router's instrumentation API.\n */\nexport function createSentryClientInstrumentation(\n options: CreateSentryClientInstrumentationOptions = {},\n): ClientInstrumentation {\n const { captureErrors = true } = options;\n\n DEBUG_BUILD && debug.log('React Router client instrumentation API created.');\n\n return {\n router(router) {\n // Set the flag when React Router actually invokes our instrumentation.\n // This ensures the flag is only set in Library Mode (where hooks run),\n // not in Framework Mode (where hooks are never called).\n // See: https://github.com/remix-run/react-router/discussions/13749\n GLOBAL_WITH_FLAGS[SENTRY_CLIENT_INSTRUMENTATION_FLAG] = true;\n DEBUG_BUILD && debug.log('React Router client instrumentation API router hook registered.');\n\n // Add popstate listener for browser back/forward navigation (persists for session, one listener only)\n if (!GLOBAL_WITH_FLAGS[SENTRY_POPSTATE_LISTENER_ADDED_FLAG] && WINDOW.addEventListener) {\n GLOBAL_WITH_FLAGS[SENTRY_POPSTATE_LISTENER_ADDED_FLAG] = true;\n\n WINDOW.addEventListener('popstate', () => {\n const client = getClient();\n if (!client) {\n currentNumericNavigationSpan = undefined;\n return;\n }\n\n const pathname = WINDOW.location?.pathname || '/';\n\n // If there's an active numeric navigation span, update it instead of creating a duplicate\n if (currentNumericNavigationSpan) {\n if (currentNumericNavigationSpan.isRecording()) {\n updateNavigationSpanUrlFromLocation(currentNumericNavigationSpan);\n }\n currentNumericNavigationSpan = undefined;\n return;\n }\n\n // Only create a new span for actual browser back/forward button clicks\n startBrowserTracingNavigationSpan(\n client,\n {\n // With span streaming, span names have to be low cardinality, so we can't fall back to\n // the URL. The route hooks parameterize the span once they resolve.\n name: hasSpanStreamingEnabled(client) ? NAVIGATION_SPAN_NAME_FALLBACK : pathname,\n attributes: {\n [SENTRY_SEGMENT_NAME_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router.instrumentation_api',\n 'navigation.type': 'browser.popstate',\n },\n },\n { url: getAbsoluteUrl(pathname) },\n );\n });\n\n DEBUG_BUILD && debug.log('React Router popstate listener registered for browser back/forward navigation.');\n }\n\n router.instrument({\n async navigate(callNavigate, info) {\n // navigate(0) triggers a page reload - skip span creation, but still capture errors\n // (navigation can be rejected before reload, e.g., by a navigation guard)\n if (info.to === 0) {\n const result = await callNavigate();\n if (result.status === 'error' && result.error instanceof Error) {\n captureInstrumentationError(result, captureErrors, 'react_router.navigate', {\n [URL_FULL]: filterCollectedUrl(info.currentUrl),\n });\n }\n return;\n }\n\n GLOBAL_WITH_FLAGS[SENTRY_NAVIGATE_HOOK_INVOKED_FLAG] = true;\n\n // Handle numeric navigations (navigate(-1), navigate(1), etc.)\n if (typeof info.to === 'number') {\n const client = getClient();\n let navigationSpan;\n\n if (client) {\n const navigationType = info.to < 0 ? 'router.back' : 'router.forward';\n const currentPathname = WINDOW.location?.pathname || info.currentUrl;\n\n navigationSpan = startBrowserTracingNavigationSpan(\n client,\n {\n // With span streaming, span names have to be low cardinality, so we can't fall back\n // to the URL. The route is resolved once the navigation settles.\n name: hasSpanStreamingEnabled(client) ? NAVIGATION_SPAN_NAME_FALLBACK : currentPathname,\n attributes: {\n [SENTRY_SEGMENT_NAME_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router.instrumentation_api',\n 'navigation.type': navigationType,\n },\n },\n { url: getAbsoluteUrl(currentPathname) },\n );\n\n // Store ref so popstate listener can update it instead of creating a duplicate\n currentNumericNavigationSpan = navigationSpan;\n }\n\n try {\n const result = await callNavigate();\n\n if (navigationSpan && WINDOW.location) {\n finalizeNavigationSpanFromHydratedRouter(navigationSpan);\n }\n\n if (result.status === 'error' && result.error instanceof Error) {\n if (navigationSpan) {\n navigationSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n }\n captureInstrumentationError(result, captureErrors, 'react_router.navigate', {\n [URL_FULL]: WINDOW.location?.pathname || filterCollectedUrl(info.currentUrl),\n });\n }\n } finally {\n currentNumericNavigationSpan = undefined;\n }\n return;\n }\n\n // Handle string/object navigations (e.g., navigate('/about') or navigate({ pathname: '/about' }))\n const client = getClient();\n const toPath = resolveNavigateArg(info.to);\n let navigationSpan;\n\n if (client) {\n navigationSpan = startBrowserTracingNavigationSpan(\n client,\n {\n // With span streaming, span names have to be low cardinality, so we can't fall back to\n // the URL. The route hooks parameterize the span once they resolve.\n name: hasSpanStreamingEnabled(client) ? NAVIGATION_SPAN_NAME_FALLBACK : toPath,\n attributes: {\n [SENTRY_SEGMENT_NAME_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router.instrumentation_api',\n 'navigation.type': 'router.navigate',\n },\n },\n { url: resolveNavigateAbsoluteUrl(info.to, info.currentUrl) },\n );\n }\n\n const result = await callNavigate();\n if (result.status === 'error' && result.error instanceof Error) {\n if (navigationSpan) {\n navigationSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n }\n captureInstrumentationError(result, captureErrors, 'react_router.navigate', {\n [URL_FULL]: filterCollectedUrl(toPath),\n });\n }\n return;\n },\n\n async fetch(callFetch, info) {\n await startSpan(\n {\n name: `Fetcher ${info.fetcherKey}`,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'fetcher',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callFetch();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.fetcher', {\n [URL_FULL]: filterCollectedUrl(info.href),\n });\n }\n },\n );\n },\n });\n },\n\n route(route) {\n const routeId = route.id;\n\n route.instrument({\n async loader(callLoader, info) {\n const urlPath = getPathFromRequest(info.request);\n const pattern = normalizeRoutePath(getPattern(info));\n const routePattern = pattern || urlPath;\n // Parameterize the active navigation root span. (Route hooks don't fire on initial\n // pageload, so this only affects navigations.)\n updateRootSpanRoute(routePattern, !!pattern);\n\n await startSpan(\n {\n name: routePattern,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'clientLoader',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callLoader();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_loader', {\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async action(callAction, info) {\n const urlPath = getPathFromRequest(info.request);\n const pattern = normalizeRoutePath(getPattern(info));\n const routePattern = pattern || urlPath;\n updateRootSpanRoute(routePattern, !!pattern);\n\n await startSpan(\n {\n name: routePattern,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'clientAction',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callAction();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_action', {\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async middleware(callMiddleware, info) {\n const urlPath = getPathFromRequest(info.request);\n const routePattern = normalizeRoutePath(getPattern(info)) || urlPath;\n\n let counters = middlewareCountersMap.get(info.request);\n if (!counters) {\n counters = {};\n middlewareCountersMap.set(info.request, counters);\n }\n\n const middlewareIndex = counters[routeId] ?? 0;\n counters[routeId] = middlewareIndex + 1;\n\n await startSpan(\n {\n name: `middleware ${routeId}`,\n attributes: {\n [SENTRY_OP]: MIDDLEWARE,\n [CODE_FUNCTION_NAME]: 'clientMiddleware',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n 'react_router.route.id': routeId,\n 'http.route': routePattern,\n 'react_router.middleware.index': middlewareIndex,\n },\n },\n async span => {\n const result = await callMiddleware();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_middleware', {\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async lazy(callLazy) {\n await startSpan(\n {\n name: 'Lazy Route Load',\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'lazy',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callLazy();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_lazy', {});\n }\n },\n );\n },\n });\n },\n };\n}\n\n/**\n * Updates the active navigation/pageload root span name with the parameterized route, so the\n * transaction reflects the parameterized route pattern (e.g. `/users/:id`).\n */\nfunction updateRootSpanRoute(routeName: string, hasPattern: boolean): void {\n if (!hasPattern) {\n return;\n }\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan && getRootSpan(activeSpan);\n if (!rootSpan) {\n return;\n }\n\n const { attributes } = spanToJSON(rootSpan);\n const op = attributes[SENTRY_OP];\n if (op !== 'navigation' && op !== 'pageload') {\n return;\n }\n\n updateSpanName(rootSpan, routeName);\n rootSpan.setAttributes({ [SENTRY_SEGMENT_NAME_SOURCE]: 'route', [URL_TEMPLATE]: routeName });\n}\n\n/**\n * Check if React Router's instrumentation API is being used on the client.\n */\nexport function isClientInstrumentationApiUsed(): boolean {\n return !!GLOBAL_WITH_FLAGS[SENTRY_CLIENT_INSTRUMENTATION_FLAG];\n}\n\n/**\n * Check if React Router's instrumentation API's navigate hook was invoked.\n */\nexport function isNavigateHookInvoked(): boolean {\n return !!GLOBAL_WITH_FLAGS[SENTRY_NAVIGATE_HOOK_INVOKED_FLAG];\n}\n"],"names":["result","client","navigationSpan"],"mappings":"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"}
1
+ {"version":3,"file":"createClientInstrumentation.js","sources":["../../../src/client/createClientInstrumentation.ts"],"sourcesContent":["// oxlint-disable max-lines\nimport { getAbsoluteUrl, startBrowserTracingNavigationSpan } from '@sentry/browser';\nimport type { Span } from '@sentry/core';\nimport {\n debug,\n getActiveSpan,\n getClient,\n getRootSpan,\n GLOBAL_OBJ,\n hasSpanStreamingEnabled,\n NAVIGATION_SPAN_NAME_FALLBACK,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n spanToJSON,\n SPAN_STATUS_ERROR,\n updateSpanName,\n filterCollectedUrl,\n} from '@sentry/core';\nimport { startSpan } from '@sentry/core/browser';\nimport type { ClientInstrumentation } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport { captureInstrumentationError, getPathFromRequest, getPattern, normalizeRoutePath } from '../common/utils';\nimport {\n resolveNavigateAbsoluteUrl,\n resolveNavigateArg,\n finalizeNavigationSpanFromHydratedRouter,\n updateNavigationSpanUrlFromLocation,\n} from './utils';\nimport {\n SENTRY_SEGMENT_NAME_SOURCE,\n CODE_FUNCTION_NAME,\n SENTRY_OP,\n URL_FULL,\n URL_TEMPLATE,\n} from '@sentry/conventions/attributes';\nimport { FUNCTION, MIDDLEWARE, NAVIGATION } from '@sentry/conventions/op';\n\nconst WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window;\n\n// Tracks active numeric navigation span to prevent duplicate spans when popstate fires\nlet currentNumericNavigationSpan: Span | undefined;\n\n// Per-request middleware counters, keyed by Request\nconst middlewareCountersMap = new WeakMap<object, Record<string, number>>();\n\nconst SENTRY_CLIENT_INSTRUMENTATION_FLAG = '__sentryReactRouterClientInstrumentationUsed';\n// Intentionally never reset - once set, instrumentation API handles all navigations for the session.\nconst SENTRY_NAVIGATE_HOOK_INVOKED_FLAG = '__sentryReactRouterNavigateHookInvoked';\nconst SENTRY_POPSTATE_LISTENER_ADDED_FLAG = '__sentryReactRouterPopstateListenerAdded';\n\ntype GlobalObjWithFlags = typeof GLOBAL_OBJ & {\n [SENTRY_CLIENT_INSTRUMENTATION_FLAG]?: boolean;\n [SENTRY_NAVIGATE_HOOK_INVOKED_FLAG]?: boolean;\n [SENTRY_POPSTATE_LISTENER_ADDED_FLAG]?: boolean;\n};\n\nconst GLOBAL_WITH_FLAGS = GLOBAL_OBJ as GlobalObjWithFlags;\n\n/**\n * Options for creating Sentry client instrumentation.\n */\nexport interface CreateSentryClientInstrumentationOptions {\n /**\n * Whether to capture errors from loaders/actions automatically.\n * Set to `false` to avoid duplicates if using custom error handlers.\n * @default true\n */\n captureErrors?: boolean;\n}\n\n/**\n * Creates a Sentry client instrumentation for React Router's instrumentation API.\n */\nexport function createSentryClientInstrumentation(\n options: CreateSentryClientInstrumentationOptions = {},\n): ClientInstrumentation {\n const { captureErrors = true } = options;\n\n DEBUG_BUILD && debug.log('React Router client instrumentation API created.');\n\n return {\n router(router) {\n // Set the flag when React Router actually invokes our instrumentation.\n // This ensures the flag is only set in Library Mode (where hooks run),\n // not in Framework Mode (where hooks are never called).\n // See: https://github.com/remix-run/react-router/discussions/13749\n GLOBAL_WITH_FLAGS[SENTRY_CLIENT_INSTRUMENTATION_FLAG] = true;\n DEBUG_BUILD && debug.log('React Router client instrumentation API router hook registered.');\n\n // Add popstate listener for browser back/forward navigation (persists for session, one listener only)\n if (!GLOBAL_WITH_FLAGS[SENTRY_POPSTATE_LISTENER_ADDED_FLAG] && WINDOW.addEventListener) {\n GLOBAL_WITH_FLAGS[SENTRY_POPSTATE_LISTENER_ADDED_FLAG] = true;\n\n WINDOW.addEventListener('popstate', () => {\n const client = getClient();\n if (!client) {\n currentNumericNavigationSpan = undefined;\n return;\n }\n\n const pathname = WINDOW.location?.pathname || '/';\n\n // If there's an active numeric navigation span, update it instead of creating a duplicate\n if (currentNumericNavigationSpan) {\n if (currentNumericNavigationSpan.isRecording()) {\n updateNavigationSpanUrlFromLocation(currentNumericNavigationSpan);\n }\n currentNumericNavigationSpan = undefined;\n return;\n }\n\n // Only create a new span for actual browser back/forward button clicks\n startBrowserTracingNavigationSpan(\n client,\n {\n // With span streaming, span names have to be low cardinality, so we can't fall back to\n // the URL. The route hooks parameterize the span once they resolve.\n name: hasSpanStreamingEnabled(client) ? NAVIGATION_SPAN_NAME_FALLBACK : pathname,\n attributes: {\n [SENTRY_SEGMENT_NAME_SOURCE]: 'url',\n [SENTRY_OP]: NAVIGATION,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router.instrumentation_api',\n 'navigation.type': 'browser.popstate',\n },\n },\n { url: getAbsoluteUrl(pathname) },\n );\n });\n\n DEBUG_BUILD && debug.log('React Router popstate listener registered for browser back/forward navigation.');\n }\n\n router.instrument({\n async navigate(callNavigate, info) {\n // navigate(0) triggers a page reload - skip span creation, but still capture errors\n // (navigation can be rejected before reload, e.g., by a navigation guard)\n if (info.to === 0) {\n const result = await callNavigate();\n if (result.status === 'error' && result.error instanceof Error) {\n captureInstrumentationError(result, captureErrors, 'react_router.navigate', {\n [URL_FULL]: filterCollectedUrl(info.currentUrl),\n });\n }\n return;\n }\n\n GLOBAL_WITH_FLAGS[SENTRY_NAVIGATE_HOOK_INVOKED_FLAG] = true;\n\n // Handle numeric navigations (navigate(-1), navigate(1), etc.)\n if (typeof info.to === 'number') {\n const client = getClient();\n let navigationSpan;\n\n if (client) {\n const navigationType = info.to < 0 ? 'router.back' : 'router.forward';\n const currentPathname = WINDOW.location?.pathname || info.currentUrl;\n\n navigationSpan = startBrowserTracingNavigationSpan(\n client,\n {\n // With span streaming, span names have to be low cardinality, so we can't fall back\n // to the URL. The route is resolved once the navigation settles.\n name: hasSpanStreamingEnabled(client) ? NAVIGATION_SPAN_NAME_FALLBACK : currentPathname,\n attributes: {\n [SENTRY_SEGMENT_NAME_SOURCE]: 'url',\n [SENTRY_OP]: NAVIGATION,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router.instrumentation_api',\n 'navigation.type': navigationType,\n },\n },\n { url: getAbsoluteUrl(currentPathname) },\n );\n\n // Store ref so popstate listener can update it instead of creating a duplicate\n currentNumericNavigationSpan = navigationSpan;\n }\n\n try {\n const result = await callNavigate();\n\n if (navigationSpan && WINDOW.location) {\n finalizeNavigationSpanFromHydratedRouter(navigationSpan);\n }\n\n if (result.status === 'error' && result.error instanceof Error) {\n if (navigationSpan) {\n navigationSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n }\n captureInstrumentationError(result, captureErrors, 'react_router.navigate', {\n [URL_FULL]: WINDOW.location?.pathname || filterCollectedUrl(info.currentUrl),\n });\n }\n } finally {\n currentNumericNavigationSpan = undefined;\n }\n return;\n }\n\n // Handle string/object navigations (e.g., navigate('/about') or navigate({ pathname: '/about' }))\n const client = getClient();\n const toPath = resolveNavigateArg(info.to);\n let navigationSpan;\n\n if (client) {\n navigationSpan = startBrowserTracingNavigationSpan(\n client,\n {\n // With span streaming, span names have to be low cardinality, so we can't fall back to\n // the URL. The route hooks parameterize the span once they resolve.\n name: hasSpanStreamingEnabled(client) ? NAVIGATION_SPAN_NAME_FALLBACK : toPath,\n attributes: {\n [SENTRY_SEGMENT_NAME_SOURCE]: 'url',\n [SENTRY_OP]: NAVIGATION,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router.instrumentation_api',\n 'navigation.type': 'router.navigate',\n },\n },\n { url: resolveNavigateAbsoluteUrl(info.to, info.currentUrl) },\n );\n }\n\n const result = await callNavigate();\n if (result.status === 'error' && result.error instanceof Error) {\n if (navigationSpan) {\n navigationSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n }\n captureInstrumentationError(result, captureErrors, 'react_router.navigate', {\n [URL_FULL]: filterCollectedUrl(toPath),\n });\n }\n return;\n },\n\n async fetch(callFetch, info) {\n await startSpan(\n {\n name: `Fetcher ${info.fetcherKey}`,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'fetcher',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callFetch();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.fetcher', {\n [URL_FULL]: filterCollectedUrl(info.href),\n });\n }\n },\n );\n },\n });\n },\n\n route(route) {\n const routeId = route.id;\n\n route.instrument({\n async loader(callLoader, info) {\n const urlPath = getPathFromRequest(info.request);\n const pattern = normalizeRoutePath(getPattern(info));\n const routePattern = pattern || urlPath;\n // Parameterize the active navigation root span. (Route hooks don't fire on initial\n // pageload, so this only affects navigations.)\n updateRootSpanRoute(routePattern, !!pattern);\n\n await startSpan(\n {\n name: routePattern,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'clientLoader',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callLoader();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_loader', {\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async action(callAction, info) {\n const urlPath = getPathFromRequest(info.request);\n const pattern = normalizeRoutePath(getPattern(info));\n const routePattern = pattern || urlPath;\n updateRootSpanRoute(routePattern, !!pattern);\n\n await startSpan(\n {\n name: routePattern,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'clientAction',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callAction();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_action', {\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async middleware(callMiddleware, info) {\n const urlPath = getPathFromRequest(info.request);\n const routePattern = normalizeRoutePath(getPattern(info)) || urlPath;\n\n let counters = middlewareCountersMap.get(info.request);\n if (!counters) {\n counters = {};\n middlewareCountersMap.set(info.request, counters);\n }\n\n const middlewareIndex = counters[routeId] ?? 0;\n counters[routeId] = middlewareIndex + 1;\n\n await startSpan(\n {\n name: `middleware ${routeId}`,\n attributes: {\n [SENTRY_OP]: MIDDLEWARE,\n [CODE_FUNCTION_NAME]: 'clientMiddleware',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n 'react_router.route.id': routeId,\n 'http.route': routePattern,\n 'react_router.middleware.index': middlewareIndex,\n },\n },\n async span => {\n const result = await callMiddleware();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_middleware', {\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async lazy(callLazy) {\n await startSpan(\n {\n name: 'Lazy Route Load',\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'lazy',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callLazy();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_lazy', {});\n }\n },\n );\n },\n });\n },\n };\n}\n\n/**\n * Updates the active navigation/pageload root span name with the parameterized route, so the\n * transaction reflects the parameterized route pattern (e.g. `/users/:id`).\n */\nfunction updateRootSpanRoute(routeName: string, hasPattern: boolean): void {\n if (!hasPattern) {\n return;\n }\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan && getRootSpan(activeSpan);\n if (!rootSpan) {\n return;\n }\n\n const { attributes } = spanToJSON(rootSpan);\n const op = attributes[SENTRY_OP];\n if (op !== 'navigation' && op !== 'pageload') {\n return;\n }\n\n updateSpanName(rootSpan, routeName);\n rootSpan.setAttributes({ [SENTRY_SEGMENT_NAME_SOURCE]: 'route', [URL_TEMPLATE]: routeName });\n}\n\n/**\n * Check if React Router's instrumentation API is being used on the client.\n */\nexport function isClientInstrumentationApiUsed(): boolean {\n return !!GLOBAL_WITH_FLAGS[SENTRY_CLIENT_INSTRUMENTATION_FLAG];\n}\n\n/**\n * Check if React Router's instrumentation API's navigate hook was invoked.\n */\nexport function isNavigateHookInvoked(): boolean {\n return !!GLOBAL_WITH_FLAGS[SENTRY_NAVIGATE_HOOK_INVOKED_FLAG];\n}\n"],"names":["result","client","navigationSpan"],"mappings":";;;;;;;;;AAoCA,MAAM,MAAA,GAAS,UAAA;AAGf,IAAI,4BAAA;AAGJ,MAAM,qBAAA,uBAA4B,OAAA,EAAwC;AAE1E,MAAM,kCAAA,GAAqC,8CAAA;AAE3C,MAAM,iCAAA,GAAoC,wCAAA;AAC1C,MAAM,mCAAA,GAAsC,0CAAA;AAQ5C,MAAM,iBAAA,GAAoB,UAAA;AAiBnB,SAAS,iCAAA,CACd,OAAA,GAAoD,EAAC,EAC9B;AACvB,EAAA,MAAM,EAAE,aAAA,GAAgB,IAAA,EAAK,GAAI,OAAA;AAEjC,EAAA,WAAA,IAAe,KAAA,CAAM,IAAI,kDAAkD,CAAA;AAE3E,EAAA,OAAO;AAAA,IACL,OAAO,MAAA,EAAQ;AAKb,MAAA,iBAAA,CAAkB,kCAAkC,CAAA,GAAI,IAAA;AACxD,MAAA,WAAA,IAAe,KAAA,CAAM,IAAI,iEAAiE,CAAA;AAG1F,MAAA,IAAI,CAAC,iBAAA,CAAkB,mCAAmC,CAAA,IAAK,OAAO,gBAAA,EAAkB;AACtF,QAAA,iBAAA,CAAkB,mCAAmC,CAAA,GAAI,IAAA;AAEzD,QAAA,MAAA,CAAO,gBAAA,CAAiB,YAAY,MAAM;AACxC,UAAA,MAAM,SAAS,SAAA,EAAU;AACzB,UAAA,IAAI,CAAC,MAAA,EAAQ;AACX,YAAA,4BAAA,GAA+B,MAAA;AAC/B,YAAA;AAAA,UACF;AAEA,UAAA,MAAM,QAAA,GAAW,MAAA,CAAO,QAAA,EAAU,QAAA,IAAY,GAAA;AAG9C,UAAA,IAAI,4BAAA,EAA8B;AAChC,YAAA,IAAI,4BAAA,CAA6B,aAAY,EAAG;AAC9C,cAAA,mCAAA,CAAoC,4BAA4B,CAAA;AAAA,YAClE;AACA,YAAA,4BAAA,GAA+B,MAAA;AAC/B,YAAA;AAAA,UACF;AAGA,UAAA,iCAAA;AAAA,YACE,MAAA;AAAA,YACA;AAAA;AAAA;AAAA,cAGE,IAAA,EAAM,uBAAA,CAAwB,MAAM,CAAA,GAAI,6BAAA,GAAgC,QAAA;AAAA,cACxE,UAAA,EAAY;AAAA,gBACV,CAAC,0BAA0B,GAAG,KAAA;AAAA,gBAC9B,CAAC,SAAS,GAAG,UAAA;AAAA,gBACb,CAAC,gCAAgC,GAAG,kDAAA;AAAA,gBACpC,iBAAA,EAAmB;AAAA;AACrB,aACF;AAAA,YACA,EAAE,GAAA,EAAK,cAAA,CAAe,QAAQ,CAAA;AAAE,WAClC;AAAA,QACF,CAAC,CAAA;AAED,QAAA,WAAA,IAAe,KAAA,CAAM,IAAI,gFAAgF,CAAA;AAAA,MAC3G;AAEA,MAAA,MAAA,CAAO,UAAA,CAAW;AAAA,QAChB,MAAM,QAAA,CAAS,YAAA,EAAc,IAAA,EAAM;AAGjC,UAAA,IAAI,IAAA,CAAK,OAAO,CAAA,EAAG;AACjB,YAAA,MAAMA,OAAAA,GAAS,MAAM,YAAA,EAAa;AAClC,YAAA,IAAIA,OAAAA,CAAO,MAAA,KAAW,OAAA,IAAWA,OAAAA,CAAO,iBAAiB,KAAA,EAAO;AAC9D,cAAA,2BAAA,CAA4BA,OAAAA,EAAQ,eAAe,uBAAA,EAAyB;AAAA,gBAC1E,CAAC,QAAQ,GAAG,kBAAA,CAAmB,KAAK,UAAU;AAAA,eAC/C,CAAA;AAAA,YACH;AACA,YAAA;AAAA,UACF;AAEA,UAAA,iBAAA,CAAkB,iCAAiC,CAAA,GAAI,IAAA;AAGvD,UAAA,IAAI,OAAO,IAAA,CAAK,EAAA,KAAO,QAAA,EAAU;AAC/B,YAAA,MAAMC,UAAS,SAAA,EAAU;AACzB,YAAA,IAAIC,eAAAA;AAEJ,YAAA,IAAID,OAAAA,EAAQ;AACV,cAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,EAAA,GAAK,CAAA,GAAI,aAAA,GAAgB,gBAAA;AACrD,cAAA,MAAM,eAAA,GAAkB,MAAA,CAAO,QAAA,EAAU,QAAA,IAAY,IAAA,CAAK,UAAA;AAE1D,cAAAC,eAAAA,GAAiB,iCAAA;AAAA,gBACfD,OAAAA;AAAA,gBACA;AAAA;AAAA;AAAA,kBAGE,IAAA,EAAM,uBAAA,CAAwBA,OAAM,CAAA,GAAI,6BAAA,GAAgC,eAAA;AAAA,kBACxE,UAAA,EAAY;AAAA,oBACV,CAAC,0BAA0B,GAAG,KAAA;AAAA,oBAC9B,CAAC,SAAS,GAAG,UAAA;AAAA,oBACb,CAAC,gCAAgC,GAAG,kDAAA;AAAA,oBACpC,iBAAA,EAAmB;AAAA;AACrB,iBACF;AAAA,gBACA,EAAE,GAAA,EAAK,cAAA,CAAe,eAAe,CAAA;AAAE,eACzC;AAGA,cAAA,4BAAA,GAA+BC,eAAAA;AAAA,YACjC;AAEA,YAAA,IAAI;AACF,cAAA,MAAMF,OAAAA,GAAS,MAAM,YAAA,EAAa;AAElC,cAAA,IAAIE,eAAAA,IAAkB,OAAO,QAAA,EAAU;AACrC,gBAAA,wCAAA,CAAyCA,eAAc,CAAA;AAAA,cACzD;AAEA,cAAA,IAAIF,OAAAA,CAAO,MAAA,KAAW,OAAA,IAAWA,OAAAA,CAAO,iBAAiB,KAAA,EAAO;AAC9D,gBAAA,IAAIE,eAAAA,EAAgB;AAClB,kBAAAA,gBAAe,SAAA,CAAU,EAAE,MAAM,iBAAA,EAAmB,OAAA,EAAS,kBAAkB,CAAA;AAAA,gBACjF;AACA,gBAAA,2BAAA,CAA4BF,OAAAA,EAAQ,eAAe,uBAAA,EAAyB;AAAA,kBAC1E,CAAC,QAAQ,GAAG,MAAA,CAAO,UAAU,QAAA,IAAY,kBAAA,CAAmB,KAAK,UAAU;AAAA,iBAC5E,CAAA;AAAA,cACH;AAAA,YACF,CAAA,SAAE;AACA,cAAA,4BAAA,GAA+B,MAAA;AAAA,YACjC;AACA,YAAA;AAAA,UACF;AAGA,UAAA,MAAM,SAAS,SAAA,EAAU;AACzB,UAAA,MAAM,MAAA,GAAS,kBAAA,CAAmB,IAAA,CAAK,EAAE,CAAA;AACzC,UAAA,IAAI,cAAA;AAEJ,UAAA,IAAI,MAAA,EAAQ;AACV,YAAA,cAAA,GAAiB,iCAAA;AAAA,cACf,MAAA;AAAA,cACA;AAAA;AAAA;AAAA,gBAGE,IAAA,EAAM,uBAAA,CAAwB,MAAM,CAAA,GAAI,6BAAA,GAAgC,MAAA;AAAA,gBACxE,UAAA,EAAY;AAAA,kBACV,CAAC,0BAA0B,GAAG,KAAA;AAAA,kBAC9B,CAAC,SAAS,GAAG,UAAA;AAAA,kBACb,CAAC,gCAAgC,GAAG,kDAAA;AAAA,kBACpC,iBAAA,EAAmB;AAAA;AACrB,eACF;AAAA,cACA,EAAE,GAAA,EAAK,0BAAA,CAA2B,KAAK,EAAA,EAAI,IAAA,CAAK,UAAU,CAAA;AAAE,aAC9D;AAAA,UACF;AAEA,UAAA,MAAM,MAAA,GAAS,MAAM,YAAA,EAAa;AAClC,UAAA,IAAI,MAAA,CAAO,MAAA,KAAW,OAAA,IAAW,MAAA,CAAO,iBAAiB,KAAA,EAAO;AAC9D,YAAA,IAAI,cAAA,EAAgB;AAClB,cAAA,cAAA,CAAe,UAAU,EAAE,IAAA,EAAM,iBAAA,EAAmB,OAAA,EAAS,kBAAkB,CAAA;AAAA,YACjF;AACA,YAAA,2BAAA,CAA4B,MAAA,EAAQ,eAAe,uBAAA,EAAyB;AAAA,cAC1E,CAAC,QAAQ,GAAG,kBAAA,CAAmB,MAAM;AAAA,aACtC,CAAA;AAAA,UACH;AACA,UAAA;AAAA,QACF,CAAA;AAAA,QAEA,MAAM,KAAA,CAAM,SAAA,EAAW,IAAA,EAAM;AAC3B,UAAA,MAAM,SAAA;AAAA,YACJ;AAAA,cACE,IAAA,EAAM,CAAA,QAAA,EAAW,IAAA,CAAK,UAAU,CAAA,CAAA;AAAA,cAChC,UAAA,EAAY;AAAA,gBACV,CAAC,SAAS,GAAG,QAAA;AAAA,gBACb,CAAC,kBAAkB,GAAG,SAAA;AAAA,gBACtB,CAAC,gCAAgC,GAAG;AAAA;AACtC,aACF;AAAA,YACA,OAAM,IAAA,KAAQ;AACZ,cAAA,MAAM,MAAA,GAAS,MAAM,SAAA,EAAU;AAC/B,cAAA,IAAI,MAAA,CAAO,MAAA,KAAW,OAAA,IAAW,MAAA,CAAO,iBAAiB,KAAA,EAAO;AAC9D,gBAAA,IAAA,CAAK,UAAU,EAAE,IAAA,EAAM,iBAAA,EAAmB,OAAA,EAAS,kBAAkB,CAAA;AACrE,gBAAA,2BAAA,CAA4B,MAAA,EAAQ,eAAe,sBAAA,EAAwB;AAAA,kBACzE,CAAC,QAAQ,GAAG,kBAAA,CAAmB,KAAK,IAAI;AAAA,iBACzC,CAAA;AAAA,cACH;AAAA,YACF;AAAA,WACF;AAAA,QACF;AAAA,OACD,CAAA;AAAA,IACH,CAAA;AAAA,IAEA,MAAM,KAAA,EAAO;AACX,MAAA,MAAM,UAAU,KAAA,CAAM,EAAA;AAEtB,MAAA,KAAA,CAAM,UAAA,CAAW;AAAA,QACf,MAAM,MAAA,CAAO,UAAA,EAAY,IAAA,EAAM;AAC7B,UAAA,MAAM,OAAA,GAAU,kBAAA,CAAmB,IAAA,CAAK,OAAO,CAAA;AAC/C,UAAA,MAAM,OAAA,GAAU,kBAAA,CAAmB,UAAA,CAAW,IAAI,CAAC,CAAA;AACnD,UAAA,MAAM,eAAe,OAAA,IAAW,OAAA;AAGhC,UAAA,mBAAA,CAAoB,YAAA,EAAc,CAAC,CAAC,OAAO,CAAA;AAE3C,UAAA,MAAM,SAAA;AAAA,YACJ;AAAA,cACE,IAAA,EAAM,YAAA;AAAA,cACN,UAAA,EAAY;AAAA,gBACV,CAAC,SAAS,GAAG,QAAA;AAAA,gBACb,CAAC,kBAAkB,GAAG,cAAA;AAAA,gBACtB,CAAC,gCAAgC,GAAG;AAAA;AACtC,aACF;AAAA,YACA,OAAM,IAAA,KAAQ;AACZ,cAAA,MAAM,MAAA,GAAS,MAAM,UAAA,EAAW;AAChC,cAAA,IAAI,MAAA,CAAO,MAAA,KAAW,OAAA,IAAW,MAAA,CAAO,iBAAiB,KAAA,EAAO;AAC9D,gBAAA,IAAA,CAAK,UAAU,EAAE,IAAA,EAAM,iBAAA,EAAmB,OAAA,EAAS,kBAAkB,CAAA;AACrE,gBAAA,2BAAA,CAA4B,MAAA,EAAQ,eAAe,4BAAA,EAA8B;AAAA,kBAC/E,CAAC,QAAQ,GAAG;AAAA,iBACb,CAAA;AAAA,cACH;AAAA,YACF;AAAA,WACF;AAAA,QACF,CAAA;AAAA,QAEA,MAAM,MAAA,CAAO,UAAA,EAAY,IAAA,EAAM;AAC7B,UAAA,MAAM,OAAA,GAAU,kBAAA,CAAmB,IAAA,CAAK,OAAO,CAAA;AAC/C,UAAA,MAAM,OAAA,GAAU,kBAAA,CAAmB,UAAA,CAAW,IAAI,CAAC,CAAA;AACnD,UAAA,MAAM,eAAe,OAAA,IAAW,OAAA;AAChC,UAAA,mBAAA,CAAoB,YAAA,EAAc,CAAC,CAAC,OAAO,CAAA;AAE3C,UAAA,MAAM,SAAA;AAAA,YACJ;AAAA,cACE,IAAA,EAAM,YAAA;AAAA,cACN,UAAA,EAAY;AAAA,gBACV,CAAC,SAAS,GAAG,QAAA;AAAA,gBACb,CAAC,kBAAkB,GAAG,cAAA;AAAA,gBACtB,CAAC,gCAAgC,GAAG;AAAA;AACtC,aACF;AAAA,YACA,OAAM,IAAA,KAAQ;AACZ,cAAA,MAAM,MAAA,GAAS,MAAM,UAAA,EAAW;AAChC,cAAA,IAAI,MAAA,CAAO,MAAA,KAAW,OAAA,IAAW,MAAA,CAAO,iBAAiB,KAAA,EAAO;AAC9D,gBAAA,IAAA,CAAK,UAAU,EAAE,IAAA,EAAM,iBAAA,EAAmB,OAAA,EAAS,kBAAkB,CAAA;AACrE,gBAAA,2BAAA,CAA4B,MAAA,EAAQ,eAAe,4BAAA,EAA8B;AAAA,kBAC/E,CAAC,QAAQ,GAAG;AAAA,iBACb,CAAA;AAAA,cACH;AAAA,YACF;AAAA,WACF;AAAA,QACF,CAAA;AAAA,QAEA,MAAM,UAAA,CAAW,cAAA,EAAgB,IAAA,EAAM;AACrC,UAAA,MAAM,OAAA,GAAU,kBAAA,CAAmB,IAAA,CAAK,OAAO,CAAA;AAC/C,UAAA,MAAM,YAAA,GAAe,kBAAA,CAAmB,UAAA,CAAW,IAAI,CAAC,CAAA,IAAK,OAAA;AAE7D,UAAA,IAAI,QAAA,GAAW,qBAAA,CAAsB,GAAA,CAAI,IAAA,CAAK,OAAO,CAAA;AACrD,UAAA,IAAI,CAAC,QAAA,EAAU;AACb,YAAA,QAAA,GAAW,EAAC;AACZ,YAAA,qBAAA,CAAsB,GAAA,CAAI,IAAA,CAAK,OAAA,EAAS,QAAQ,CAAA;AAAA,UAClD;AAEA,UAAA,MAAM,eAAA,GAAkB,QAAA,CAAS,OAAO,CAAA,IAAK,CAAA;AAC7C,UAAA,QAAA,CAAS,OAAO,IAAI,eAAA,GAAkB,CAAA;AAEtC,UAAA,MAAM,SAAA;AAAA,YACJ;AAAA,cACE,IAAA,EAAM,cAAc,OAAO,CAAA,CAAA;AAAA,cAC3B,UAAA,EAAY;AAAA,gBACV,CAAC,SAAS,GAAG,UAAA;AAAA,gBACb,CAAC,kBAAkB,GAAG,kBAAA;AAAA,gBACtB,CAAC,gCAAgC,GAAG,gDAAA;AAAA,gBACpC,uBAAA,EAAyB,OAAA;AAAA,gBACzB,YAAA,EAAc,YAAA;AAAA,gBACd,+BAAA,EAAiC;AAAA;AACnC,aACF;AAAA,YACA,OAAM,IAAA,KAAQ;AACZ,cAAA,MAAM,MAAA,GAAS,MAAM,cAAA,EAAe;AACpC,cAAA,IAAI,MAAA,CAAO,MAAA,KAAW,OAAA,IAAW,MAAA,CAAO,iBAAiB,KAAA,EAAO;AAC9D,gBAAA,IAAA,CAAK,UAAU,EAAE,IAAA,EAAM,iBAAA,EAAmB,OAAA,EAAS,kBAAkB,CAAA;AACrE,gBAAA,2BAAA,CAA4B,MAAA,EAAQ,eAAe,gCAAA,EAAkC;AAAA,kBACnF,CAAC,QAAQ,GAAG;AAAA,iBACb,CAAA;AAAA,cACH;AAAA,YACF;AAAA,WACF;AAAA,QACF,CAAA;AAAA,QAEA,MAAM,KAAK,QAAA,EAAU;AACnB,UAAA,MAAM,SAAA;AAAA,YACJ;AAAA,cACE,IAAA,EAAM,iBAAA;AAAA,cACN,UAAA,EAAY;AAAA,gBACV,CAAC,SAAS,GAAG,QAAA;AAAA,gBACb,CAAC,kBAAkB,GAAG,MAAA;AAAA,gBACtB,CAAC,gCAAgC,GAAG;AAAA;AACtC,aACF;AAAA,YACA,OAAM,IAAA,KAAQ;AACZ,cAAA,MAAM,MAAA,GAAS,MAAM,QAAA,EAAS;AAC9B,cAAA,IAAI,MAAA,CAAO,MAAA,KAAW,OAAA,IAAW,MAAA,CAAO,iBAAiB,KAAA,EAAO;AAC9D,gBAAA,IAAA,CAAK,UAAU,EAAE,IAAA,EAAM,iBAAA,EAAmB,OAAA,EAAS,kBAAkB,CAAA;AACrE,gBAAA,2BAAA,CAA4B,MAAA,EAAQ,aAAA,EAAe,0BAAA,EAA4B,EAAE,CAAA;AAAA,cACnF;AAAA,YACF;AAAA,WACF;AAAA,QACF;AAAA,OACD,CAAA;AAAA,IACH;AAAA,GACF;AACF;AAMA,SAAS,mBAAA,CAAoB,WAAmB,UAAA,EAA2B;AACzE,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,aAAa,aAAA,EAAc;AACjC,EAAA,MAAM,QAAA,GAAW,UAAA,IAAc,WAAA,CAAY,UAAU,CAAA;AACrD,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,EAAE,UAAA,EAAW,GAAI,UAAA,CAAW,QAAQ,CAAA;AAC1C,EAAA,MAAM,EAAA,GAAK,WAAW,SAAS,CAAA;AAC/B,EAAA,IAAI,EAAA,KAAO,YAAA,IAAgB,EAAA,KAAO,UAAA,EAAY;AAC5C,IAAA;AAAA,EACF;AAEA,EAAA,cAAA,CAAe,UAAU,SAAS,CAAA;AAClC,EAAA,QAAA,CAAS,aAAA,CAAc,EAAE,CAAC,0BAA0B,GAAG,SAAS,CAAC,YAAY,GAAG,SAAA,EAAW,CAAA;AAC7F;AAKO,SAAS,8BAAA,GAA0C;AACxD,EAAA,OAAO,CAAC,CAAC,iBAAA,CAAkB,kCAAkC,CAAA;AAC/D;AAKO,SAAS,qBAAA,GAAiC;AAC/C,EAAA,OAAO,CAAC,CAAC,iBAAA,CAAkB,iCAAiC,CAAA;AAC9D;;;;"}
@@ -1,9 +1,10 @@
1
1
  import { getAbsoluteUrl, startBrowserTracingNavigationSpan } from '@sentry/browser';
2
- import { GLOBAL_OBJ, spanToJSON, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, isThenable, debug, getActiveSpan, getRootSpan, getClient, NAVIGATION_SPAN_NAME_FALLBACK, SEMANTIC_ATTRIBUTE_SENTRY_OP, hasSpanStreamingEnabled } from '@sentry/core';
2
+ import { GLOBAL_OBJ, spanToJSON, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, isThenable, debug, getActiveSpan, getRootSpan, getClient, NAVIGATION_SPAN_NAME_FALLBACK, hasSpanStreamingEnabled } from '@sentry/core';
3
3
  import { DEBUG_BUILD } from '../common/debug-build.js';
4
4
  import { isClientInstrumentationApiUsed } from './createClientInstrumentation.js';
5
5
  import { normalizePathname, updateSpanWithParameterizedRoute, finalizeNavigationSpanFromRouterState, resolveNavigateAbsoluteUrl, resolveNavigateArg } from './utils.js';
6
6
  import { URL_PATH, SENTRY_OP, SENTRY_SEGMENT_NAME_SOURCE } from '@sentry/conventions/attributes';
7
+ import { NAVIGATION } from '@sentry/conventions/op';
7
8
 
8
9
  const GLOBAL_OBJ_WITH_DATA_ROUTER = GLOBAL_OBJ;
9
10
  const WINDOW = GLOBAL_OBJ;
@@ -107,7 +108,7 @@ function maybeCreateNavigationTransaction(name, url, source) {
107
108
  name: !hasSpanStreamingEnabled(client) ? name : NAVIGATION_SPAN_NAME_FALLBACK,
108
109
  attributes: {
109
110
  [SENTRY_SEGMENT_NAME_SOURCE]: source,
110
- [SEMANTIC_ATTRIBUTE_SENTRY_OP]: "navigation",
111
+ [SENTRY_OP]: NAVIGATION,
111
112
  [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.navigation.react_router",
112
113
  ...{}
113
114
  }
@@ -1 +1 @@
1
- {"version":3,"file":"hydratedRouter.js","sources":["../../../src/client/hydratedRouter.ts"],"sourcesContent":["import { getAbsoluteUrl, startBrowserTracingNavigationSpan } from '@sentry/browser';\nimport type { Span } from '@sentry/core';\nimport {\n debug,\n getActiveSpan,\n getClient,\n getRootSpan,\n GLOBAL_OBJ,\n hasSpanStreamingEnabled,\n isThenable,\n NAVIGATION_SPAN_NAME_FALLBACK,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n spanToJSON,\n} from '@sentry/core';\nimport type { DataRouter } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport { isClientInstrumentationApiUsed } from './createClientInstrumentation';\nimport {\n finalizeNavigationSpanFromRouterState,\n normalizePathname,\n resolveNavigateAbsoluteUrl,\n resolveNavigateArg,\n updateSpanWithParameterizedRoute,\n} from './utils';\nimport { SENTRY_SEGMENT_NAME_SOURCE, SENTRY_OP, URL_PATH, URL_TEMPLATE } from '@sentry/conventions/attributes';\n\nconst GLOBAL_OBJ_WITH_DATA_ROUTER = GLOBAL_OBJ as typeof GLOBAL_OBJ & {\n __reactRouterDataRouter?: DataRouter;\n};\n\nconst WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window;\n\nconst MAX_RETRIES = 40; // 2 seconds at 50ms interval\n\n/**\n * Instruments the React Router Data Router for pageloads and navigation.\n *\n * This function waits for the router to be available after hydration, then:\n * 1. Updates the pageload transaction with parameterized route info\n * 2. Patches router.navigate() to create navigation transactions\n * 3. Subscribes to router state changes to update navigation transactions with parameterized routes\n */\nexport function instrumentHydratedRouter(): void {\n function trySubscribe(): boolean {\n const router = GLOBAL_OBJ_WITH_DATA_ROUTER.__reactRouterDataRouter;\n\n if (router) {\n // The first time we hit the router, we try to update the pageload transaction\n const pageloadSpan = getActiveRootSpan();\n\n if (pageloadSpan) {\n // Matched against `url.path` rather than the span name: with span streaming, the pageload\n // span is named `Pageload` until a route is resolved, so the name may not hold the pathname.\n const pageloadPath = spanToJSON(pageloadSpan).attributes[URL_PATH];\n if (\n typeof pageloadPath === 'string' &&\n // this event is for the currently active pageload\n normalizePathname(router.state.location.pathname) === normalizePathname(pageloadPath)\n ) {\n pageloadSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.pageload.react_router');\n updateSpanWithParameterizedRoute(pageloadSpan, router.state);\n }\n }\n\n // Patching navigate for creating accurate navigation transactions\n if (typeof router.navigate === 'function') {\n const originalNav = router.navigate.bind(router);\n router.navigate = function sentryPatchedNavigate(...args) {\n // Skip if instrumentation API is enabled (it handles navigation spans itself)\n if (!isClientInstrumentationApiUsed()) {\n const target = args[0];\n\n if (typeof target === 'number') {\n // navigate(0) triggers a reload, not a route change — skip span creation\n if (target !== 0) {\n const currentPathname = WINDOW.location?.pathname || '/';\n const navigationSpan = maybeCreateNavigationTransaction(\n currentPathname,\n getAbsoluteUrl(currentPathname),\n 'url',\n );\n\n const result = originalNav(...args);\n\n // Numeric navigations (`navigate(-1)`/`navigate(1)`) don't carry a destination\n // path, so we can only resolve the real URL/route once the router has settled.\n if (navigationSpan) {\n // Finalize from the (updated) router state after navigation completes, in both\n // the resolve and reject paths, so a rejected navigation still ends up with the\n // correct URL attributes instead of the placeholder start pathname.\n if (isThenable(result)) {\n result.then(\n () => finalizeNavigationSpanFromRouterState(navigationSpan, router.state),\n () => finalizeNavigationSpanFromRouterState(navigationSpan, router.state),\n );\n } else {\n finalizeNavigationSpanFromRouterState(navigationSpan, router.state);\n }\n }\n\n return result;\n }\n } else {\n maybeCreateNavigationTransaction(\n resolveNavigateArg(target) || '<unknown route>',\n resolveNavigateAbsoluteUrl(target),\n 'url',\n );\n }\n }\n return originalNav(...args);\n };\n }\n\n // Subscribe to router state changes to update navigation transactions (and any pageload\n // whose route info only became available after `trySubscribe`, e.g. lazy routes) with the\n // parameterized route.\n router.subscribe(newState => {\n const rootSpan = getActiveRootSpan();\n\n if (!rootSpan) {\n return;\n }\n\n const rootSpanJson = spanToJSON(rootSpan);\n const rootSpanAttributes = rootSpanJson.attributes;\n\n // When the instrumentation API is active, navigation roots are parameterized\n // by the native route hooks\n if (\n rootSpanAttributes[SENTRY_OP] === 'navigation' &&\n isClientInstrumentationApiUsed() &&\n rootSpanAttributes[SENTRY_SEGMENT_NAME_SOURCE] === 'route'\n ) {\n return;\n }\n\n const rootSpanName = rootSpanJson.name;\n const spanPathname = rootSpanAttributes[URL_PATH] as string | undefined;\n const destinationPathname = normalizePathname(newState.location.pathname);\n\n if (\n rootSpanName &&\n newState.navigation.state === 'idle' && // navigation has completed\n // this event is for the currently active root span\n (destinationPathname === normalizePathname(rootSpanName) ||\n (spanPathname && destinationPathname === normalizePathname(spanPathname)))\n ) {\n updateSpanWithParameterizedRoute(rootSpan, newState);\n }\n });\n return true;\n }\n return false;\n }\n\n // Wait until the router is available (since the SDK loads before hydration)\n if (!trySubscribe()) {\n let retryCount = 0;\n // Retry until the router is available or max retries reached\n const interval = setInterval(() => {\n if (trySubscribe() || retryCount >= MAX_RETRIES) {\n if (retryCount >= MAX_RETRIES) {\n DEBUG_BUILD && debug.warn('Unable to instrument React Router: router not found after hydration.');\n }\n clearInterval(interval);\n }\n retryCount++;\n }, 50);\n }\n}\n\nfunction maybeCreateNavigationTransaction(name: string, url: string, source: 'url' | 'route'): Span | undefined {\n const client = getClient();\n\n if (!client) {\n return undefined;\n }\n\n return startBrowserTracingNavigationSpan(\n client,\n {\n // With span streaming, span names have to be low cardinality, so we can't fall back to the URL.\n // The route is resolved once the router settles, which updates the span name then.\n name: source === 'route' || !hasSpanStreamingEnabled(client) ? name : NAVIGATION_SPAN_NAME_FALLBACK,\n attributes: {\n [SENTRY_SEGMENT_NAME_SOURCE]: source,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router',\n ...(source === 'route' ? { [URL_TEMPLATE]: name } : {}),\n },\n },\n { url },\n );\n}\n\nfunction getActiveRootSpan(): Span | undefined {\n const activeSpan = getActiveSpan();\n if (!activeSpan) {\n return undefined;\n }\n\n const rootSpan = getRootSpan(activeSpan);\n\n const op = spanToJSON(rootSpan).attributes[SENTRY_OP];\n\n // Only use this root span if it is a pageload or navigation span\n return op === 'navigation' || op === 'pageload' ? rootSpan : undefined;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hydratedRouter.js","sources":["../../../src/client/hydratedRouter.ts"],"sourcesContent":["import { getAbsoluteUrl, startBrowserTracingNavigationSpan } from '@sentry/browser';\nimport type { Span } from '@sentry/core';\nimport {\n debug,\n getActiveSpan,\n getClient,\n getRootSpan,\n GLOBAL_OBJ,\n hasSpanStreamingEnabled,\n isThenable,\n NAVIGATION_SPAN_NAME_FALLBACK,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n spanToJSON,\n} from '@sentry/core';\nimport type { DataRouter } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport { isClientInstrumentationApiUsed } from './createClientInstrumentation';\nimport {\n finalizeNavigationSpanFromRouterState,\n normalizePathname,\n resolveNavigateAbsoluteUrl,\n resolveNavigateArg,\n updateSpanWithParameterizedRoute,\n} from './utils';\nimport { SENTRY_SEGMENT_NAME_SOURCE, SENTRY_OP, URL_PATH, URL_TEMPLATE } from '@sentry/conventions/attributes';\nimport { NAVIGATION } from '@sentry/conventions/op';\n\nconst GLOBAL_OBJ_WITH_DATA_ROUTER = GLOBAL_OBJ as typeof GLOBAL_OBJ & {\n __reactRouterDataRouter?: DataRouter;\n};\n\nconst WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window;\n\nconst MAX_RETRIES = 40; // 2 seconds at 50ms interval\n\n/**\n * Instruments the React Router Data Router for pageloads and navigation.\n *\n * This function waits for the router to be available after hydration, then:\n * 1. Updates the pageload transaction with parameterized route info\n * 2. Patches router.navigate() to create navigation transactions\n * 3. Subscribes to router state changes to update navigation transactions with parameterized routes\n */\nexport function instrumentHydratedRouter(): void {\n function trySubscribe(): boolean {\n const router = GLOBAL_OBJ_WITH_DATA_ROUTER.__reactRouterDataRouter;\n\n if (router) {\n // The first time we hit the router, we try to update the pageload transaction\n const pageloadSpan = getActiveRootSpan();\n\n if (pageloadSpan) {\n // Matched against `url.path` rather than the span name: with span streaming, the pageload\n // span is named `Pageload` until a route is resolved, so the name may not hold the pathname.\n const pageloadPath = spanToJSON(pageloadSpan).attributes[URL_PATH];\n if (\n typeof pageloadPath === 'string' &&\n // this event is for the currently active pageload\n normalizePathname(router.state.location.pathname) === normalizePathname(pageloadPath)\n ) {\n pageloadSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.pageload.react_router');\n updateSpanWithParameterizedRoute(pageloadSpan, router.state);\n }\n }\n\n // Patching navigate for creating accurate navigation transactions\n if (typeof router.navigate === 'function') {\n const originalNav = router.navigate.bind(router);\n router.navigate = function sentryPatchedNavigate(...args) {\n // Skip if instrumentation API is enabled (it handles navigation spans itself)\n if (!isClientInstrumentationApiUsed()) {\n const target = args[0];\n\n if (typeof target === 'number') {\n // navigate(0) triggers a reload, not a route change — skip span creation\n if (target !== 0) {\n const currentPathname = WINDOW.location?.pathname || '/';\n const navigationSpan = maybeCreateNavigationTransaction(\n currentPathname,\n getAbsoluteUrl(currentPathname),\n 'url',\n );\n\n const result = originalNav(...args);\n\n // Numeric navigations (`navigate(-1)`/`navigate(1)`) don't carry a destination\n // path, so we can only resolve the real URL/route once the router has settled.\n if (navigationSpan) {\n // Finalize from the (updated) router state after navigation completes, in both\n // the resolve and reject paths, so a rejected navigation still ends up with the\n // correct URL attributes instead of the placeholder start pathname.\n if (isThenable(result)) {\n result.then(\n () => finalizeNavigationSpanFromRouterState(navigationSpan, router.state),\n () => finalizeNavigationSpanFromRouterState(navigationSpan, router.state),\n );\n } else {\n finalizeNavigationSpanFromRouterState(navigationSpan, router.state);\n }\n }\n\n return result;\n }\n } else {\n maybeCreateNavigationTransaction(\n resolveNavigateArg(target) || '<unknown route>',\n resolveNavigateAbsoluteUrl(target),\n 'url',\n );\n }\n }\n return originalNav(...args);\n };\n }\n\n // Subscribe to router state changes to update navigation transactions (and any pageload\n // whose route info only became available after `trySubscribe`, e.g. lazy routes) with the\n // parameterized route.\n router.subscribe(newState => {\n const rootSpan = getActiveRootSpan();\n\n if (!rootSpan) {\n return;\n }\n\n const rootSpanJson = spanToJSON(rootSpan);\n const rootSpanAttributes = rootSpanJson.attributes;\n\n // When the instrumentation API is active, navigation roots are parameterized\n // by the native route hooks\n if (\n rootSpanAttributes[SENTRY_OP] === 'navigation' &&\n isClientInstrumentationApiUsed() &&\n rootSpanAttributes[SENTRY_SEGMENT_NAME_SOURCE] === 'route'\n ) {\n return;\n }\n\n const rootSpanName = rootSpanJson.name;\n const spanPathname = rootSpanAttributes[URL_PATH] as string | undefined;\n const destinationPathname = normalizePathname(newState.location.pathname);\n\n if (\n rootSpanName &&\n newState.navigation.state === 'idle' && // navigation has completed\n // this event is for the currently active root span\n (destinationPathname === normalizePathname(rootSpanName) ||\n (spanPathname && destinationPathname === normalizePathname(spanPathname)))\n ) {\n updateSpanWithParameterizedRoute(rootSpan, newState);\n }\n });\n return true;\n }\n return false;\n }\n\n // Wait until the router is available (since the SDK loads before hydration)\n if (!trySubscribe()) {\n let retryCount = 0;\n // Retry until the router is available or max retries reached\n const interval = setInterval(() => {\n if (trySubscribe() || retryCount >= MAX_RETRIES) {\n if (retryCount >= MAX_RETRIES) {\n DEBUG_BUILD && debug.warn('Unable to instrument React Router: router not found after hydration.');\n }\n clearInterval(interval);\n }\n retryCount++;\n }, 50);\n }\n}\n\nfunction maybeCreateNavigationTransaction(name: string, url: string, source: 'url' | 'route'): Span | undefined {\n const client = getClient();\n\n if (!client) {\n return undefined;\n }\n\n return startBrowserTracingNavigationSpan(\n client,\n {\n // With span streaming, span names have to be low cardinality, so we can't fall back to the URL.\n // The route is resolved once the router settles, which updates the span name then.\n name: source === 'route' || !hasSpanStreamingEnabled(client) ? name : NAVIGATION_SPAN_NAME_FALLBACK,\n attributes: {\n [SENTRY_SEGMENT_NAME_SOURCE]: source,\n [SENTRY_OP]: NAVIGATION,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router',\n ...(source === 'route' ? { [URL_TEMPLATE]: name } : {}),\n },\n },\n { url },\n );\n}\n\nfunction getActiveRootSpan(): Span | undefined {\n const activeSpan = getActiveSpan();\n if (!activeSpan) {\n return undefined;\n }\n\n const rootSpan = getRootSpan(activeSpan);\n\n const op = spanToJSON(rootSpan).attributes[SENTRY_OP];\n\n // Only use this root span if it is a pageload or navigation span\n return op === 'navigation' || op === 'pageload' ? rootSpan : undefined;\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"type":"module","version":"11.0.0-alpha.2"}
1
+ {"type":"module","version":"11.0.0-beta.0"}
@@ -1,4 +1,5 @@
1
- import { captureException, flushIfServerless } from '@sentry/core';
1
+ import { captureException } from '@sentry/core';
2
+ import { flushIfServerless } from '@sentry/core/server';
2
3
 
3
4
  function createSentryHandleError({ logErrors = false }) {
4
5
  const handleError = async function handleError2(error, args) {
@@ -1 +1 @@
1
- {"version":3,"file":"createSentryHandleError.js","sources":["../../../src/server/createSentryHandleError.ts"],"sourcesContent":["import { captureException, flushIfServerless } from '@sentry/core';\nimport type { HandleErrorFunction } from 'react-router';\n\nexport type SentryHandleErrorOptions = {\n logErrors?: boolean;\n};\n\n/**\n * A complete Sentry-instrumented handleError implementation that handles error reporting\n *\n * @returns A Sentry-instrumented handleError function\n */\nexport function createSentryHandleError({ logErrors = false }: SentryHandleErrorOptions): HandleErrorFunction {\n const handleError: HandleErrorFunction = async function handleError(error, args): Promise<void> {\n // React Router may abort some interrupted requests, don't report those\n if (!args.request.signal.aborted) {\n captureException(error, {\n mechanism: {\n type: 'react-router',\n handled: false,\n },\n });\n if (logErrors) {\n // eslint-disable-next-line no-console\n console.error(error);\n }\n try {\n await flushIfServerless();\n } catch {\n // Ignore flush errors to ensure error handling completes gracefully\n }\n }\n };\n\n return handleError;\n}\n"],"names":["handleError"],"mappings":";;AAYO,SAAS,uBAAA,CAAwB,EAAE,SAAA,GAAY,KAAA,EAAM,EAAkD;AAC5G,EAAA,MAAM,WAAA,GAAmC,eAAeA,YAAAA,CAAY,KAAA,EAAO,IAAA,EAAqB;AAE9F,IAAA,IAAI,CAAC,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,OAAA,EAAS;AAChC,MAAA,gBAAA,CAAiB,KAAA,EAAO;AAAA,QACtB,SAAA,EAAW;AAAA,UACT,IAAA,EAAM,cAAA;AAAA,UACN,OAAA,EAAS;AAAA;AACX,OACD,CAAA;AACD,MAAA,IAAI,SAAA,EAAW;AAEb,QAAA,OAAA,CAAQ,MAAM,KAAK,CAAA;AAAA,MACrB;AACA,MAAA,IAAI;AACF,QAAA,MAAM,iBAAA,EAAkB;AAAA,MAC1B,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,CAAA;AAEA,EAAA,OAAO,WAAA;AACT;;;;"}
1
+ {"version":3,"file":"createSentryHandleError.js","sources":["../../../src/server/createSentryHandleError.ts"],"sourcesContent":["import { captureException } from '@sentry/core';\nimport { flushIfServerless } from '@sentry/core/server';\nimport type { HandleErrorFunction } from 'react-router';\n\nexport type SentryHandleErrorOptions = {\n logErrors?: boolean;\n};\n\n/**\n * A complete Sentry-instrumented handleError implementation that handles error reporting\n *\n * @returns A Sentry-instrumented handleError function\n */\nexport function createSentryHandleError({ logErrors = false }: SentryHandleErrorOptions): HandleErrorFunction {\n const handleError: HandleErrorFunction = async function handleError(error, args): Promise<void> {\n // React Router may abort some interrupted requests, don't report those\n if (!args.request.signal.aborted) {\n captureException(error, {\n mechanism: {\n type: 'react-router',\n handled: false,\n },\n });\n if (logErrors) {\n // eslint-disable-next-line no-console\n console.error(error);\n }\n try {\n await flushIfServerless();\n } catch {\n // Ignore flush errors to ensure error handling completes gracefully\n }\n }\n };\n\n return handleError;\n}\n"],"names":["handleError"],"mappings":";;;AAaO,SAAS,uBAAA,CAAwB,EAAE,SAAA,GAAY,KAAA,EAAM,EAAkD;AAC5G,EAAA,MAAM,WAAA,GAAmC,eAAeA,YAAAA,CAAY,KAAA,EAAO,IAAA,EAAqB;AAE9F,IAAA,IAAI,CAAC,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,OAAA,EAAS;AAChC,MAAA,gBAAA,CAAiB,KAAA,EAAO;AAAA,QACtB,SAAA,EAAW;AAAA,UACT,IAAA,EAAM,cAAA;AAAA,UACN,OAAA,EAAS;AAAA;AACX,OACD,CAAA;AACD,MAAA,IAAI,SAAA,EAAW;AAEb,QAAA,OAAA,CAAQ,MAAM,KAAK,CAAA;AAAA,MACrB;AACA,MAAA,IAAI;AACF,QAAA,MAAM,iBAAA,EAAkB;AAAA,MAC1B,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,CAAA;AAEA,EAAA,OAAO,WAAA;AACT;;;;"}
@@ -1,6 +1,7 @@
1
1
  import { CODE_FUNCTION_NAME, SENTRY_OP, HTTP_ROUTE, HTTP_REQUEST_METHOD, URL_PATH, URL_FULL, SENTRY_SEGMENT_NAME_SOURCE } from '@sentry/conventions/attributes';
2
- import { FUNCTION, MIDDLEWARE } from '@sentry/conventions/op';
3
- import { debug, startSpan, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_STATUS_ERROR, getActiveSpan, getRootSpan, getClient, hasSpanStreamingEnabled, HTTP_SPAN_NAME_FALLBACK, updateSpanName, filterCollectedUrl, SEMANTIC_ATTRIBUTE_SENTRY_OP, flushIfServerless, getCurrentScope } from '@sentry/core';
2
+ import { FUNCTION, MIDDLEWARE, HTTP_SERVER } from '@sentry/conventions/op';
3
+ import { debug, startSpan, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_STATUS_ERROR, getActiveSpan, getRootSpan, getClient, hasSpanStreamingEnabled, HTTP_SPAN_NAME_FALLBACK, updateSpanName, filterCollectedUrl, getCurrentScope } from '@sentry/core';
4
+ import { flushIfServerless } from '@sentry/core/server';
4
5
  import { DEBUG_BUILD } from '../common/debug-build.js';
5
6
  import { captureInstrumentationError, getPathFromRequest, getPattern, normalizeRoutePath } from '../common/utils.js';
6
7
  import { getMiddlewareName } from './serverBuild.js';
@@ -24,7 +25,7 @@ function createSentryServerInstrumentation(options = {}) {
24
25
  if (existingRootSpan) {
25
26
  updateSpanName(existingRootSpan, unparameterizedName);
26
27
  existingRootSpan.setAttributes({
27
- [SEMANTIC_ATTRIBUTE_SENTRY_OP]: "http.server",
28
+ [SENTRY_OP]: HTTP_SERVER,
28
29
  [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.http.react_router.instrumentation_api",
29
30
  [SENTRY_SEGMENT_NAME_SOURCE]: "url",
30
31
  [URL_FULL]: filterCollectedUrl(info.request.url),
@@ -46,9 +47,8 @@ function createSentryServerInstrumentation(options = {}) {
46
47
  await startSpan(
47
48
  {
48
49
  name: unparameterizedName,
49
- forceTransaction: true,
50
50
  attributes: {
51
- [SEMANTIC_ATTRIBUTE_SENTRY_OP]: "http.server",
51
+ [SENTRY_OP]: HTTP_SERVER,
52
52
  [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.http.react_router.instrumentation_api",
53
53
  [SENTRY_SEGMENT_NAME_SOURCE]: "url",
54
54
  [HTTP_REQUEST_METHOD]: info.request.method,
@@ -1 +1 @@
1
- {"version":3,"file":"createServerInstrumentation.js","sources":["../../../src/server/createServerInstrumentation.ts"],"sourcesContent":["import {\n SENTRY_SEGMENT_NAME_SOURCE,\n CODE_FUNCTION_NAME,\n HTTP_REQUEST_METHOD,\n HTTP_ROUTE,\n SENTRY_OP,\n URL_FULL,\n URL_PATH,\n} from '@sentry/conventions/attributes';\nimport { FUNCTION, MIDDLEWARE } from '@sentry/conventions/op';\nimport {\n debug,\n flushIfServerless,\n getActiveSpan,\n getClient,\n getCurrentScope,\n getRootSpan,\n hasSpanStreamingEnabled,\n HTTP_SPAN_NAME_FALLBACK,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SPAN_STATUS_ERROR,\n startSpan,\n updateSpanName,\n filterCollectedUrl,\n} from '@sentry/core';\nimport type { ServerInstrumentation } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport { captureInstrumentationError, getPathFromRequest, getPattern, normalizeRoutePath } from '../common/utils';\nimport { getMiddlewareName } from './serverBuild';\nimport { markInstrumentationApiUsed } from './serverGlobals';\n\n// Per-request middleware counters, keyed by the request's root span (the one transaction all of a\n// request's middlewares run under). The root span is the same instance across those middleware hooks\n// whether or not a Sentry OpenTelemetry tracer provider is set up, unlike the OTel context the counter\n// used to live on (which does not propagate without a provider).\nconst middlewareCountersByRootSpan = new WeakMap<object, Record<string, number>>();\n\n// Re-export for backward compatibility and external use\nexport { isInstrumentationApiUsed } from './serverGlobals';\n\n/**\n * Options for creating Sentry server instrumentation.\n */\nexport interface CreateSentryServerInstrumentationOptions {\n /**\n * Whether to capture errors from loaders/actions automatically.\n * @default true\n */\n captureErrors?: boolean;\n}\n\n/**\n * Creates a Sentry server instrumentation for React Router's instrumentation API.\n */\nexport function createSentryServerInstrumentation(\n options: CreateSentryServerInstrumentationOptions = {},\n): ServerInstrumentation {\n const { captureErrors = true } = options;\n\n DEBUG_BUILD && debug.log('React Router server instrumentation created.');\n\n return {\n handler(handler) {\n // Mark the instrumentation API active only when React Router actually invokes this\n markInstrumentationApiUsed();\n handler.instrument({\n async request(handleRequest, info) {\n const pathname = getPathFromRequest(info.request);\n const activeSpan = getActiveSpan();\n const existingRootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;\n\n const client = getClient();\n // With span streaming, span names have to be low cardinality, so we can't fall back to the URL\n // path. `updateRootSpanWithRoute` renames the span once React Router matches a route.\n const unparameterizedName =\n client && hasSpanStreamingEnabled(client)\n ? info.request.method?.toUpperCase() || HTTP_SPAN_NAME_FALLBACK\n : `${info.request.method} ${pathname}`;\n\n if (existingRootSpan) {\n updateSpanName(existingRootSpan, unparameterizedName);\n existingRootSpan.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.server',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.instrumentation_api',\n [SENTRY_SEGMENT_NAME_SOURCE]: 'url',\n [URL_FULL]: filterCollectedUrl(info.request.url),\n [URL_PATH]: pathname,\n });\n\n try {\n const result = await handleRequest();\n if (result.status === 'error' && result.error instanceof Error) {\n existingRootSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.request_handler', {\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_FULL]: pathname,\n });\n }\n } finally {\n await flushIfServerless();\n }\n } else {\n await startSpan(\n {\n name: unparameterizedName,\n forceTransaction: true,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.server',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.instrumentation_api',\n [SENTRY_SEGMENT_NAME_SOURCE]: 'url',\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_PATH]: pathname,\n [URL_FULL]: filterCollectedUrl(info.request.url),\n },\n },\n async span => {\n try {\n const result = await handleRequest();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.request_handler', {\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_FULL]: pathname,\n });\n }\n } finally {\n await flushIfServerless();\n }\n },\n );\n }\n },\n });\n },\n\n route(route) {\n // Also mark active here, in case route registration runs (mirrors the handler callback above).\n markInstrumentationApiUsed();\n const routeId = route.id;\n\n route.instrument({\n async loader(callLoader, info) {\n const urlPath = getPathFromRequest(info.request);\n const pattern = getPattern(info);\n const routePattern = normalizeRoutePath(pattern) || urlPath;\n updateRootSpanWithRoute(info.request.method, pattern, urlPath);\n\n await startSpan(\n {\n name: routePattern,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'loader',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callLoader();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.loader', {\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async action(callAction, info) {\n const urlPath = getPathFromRequest(info.request);\n const pattern = getPattern(info);\n const routePattern = normalizeRoutePath(pattern) || urlPath;\n updateRootSpanWithRoute(info.request.method, pattern, urlPath);\n\n await startSpan(\n {\n name: routePattern,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'action',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callAction();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.action', {\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async middleware(callMiddleware, info) {\n const urlPath = getPathFromRequest(info.request);\n const pattern = getPattern(info);\n const routePattern = normalizeRoutePath(pattern) || urlPath;\n\n updateRootSpanWithRoute(info.request.method, pattern, urlPath);\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;\n let middlewareIndex = 0;\n if (rootSpan) {\n let counters = middlewareCountersByRootSpan.get(rootSpan);\n if (!counters) {\n counters = {};\n middlewareCountersByRootSpan.set(rootSpan, counters);\n }\n middlewareIndex = counters[routeId] ?? 0;\n counters[routeId] = middlewareIndex + 1;\n }\n\n const middlewareName = getMiddlewareName(routeId, middlewareIndex);\n\n await startSpan(\n {\n name: `middleware ${middlewareName || routeId}`,\n attributes: {\n [SENTRY_OP]: MIDDLEWARE,\n [CODE_FUNCTION_NAME]: 'middleware',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n 'react_router.route.id': routeId,\n [HTTP_ROUTE]: routePattern,\n ...(middlewareName && { 'react_router.middleware.name': middlewareName }),\n 'react_router.middleware.index': middlewareIndex,\n },\n },\n async span => {\n const result = await callMiddleware();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.middleware', {\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async lazy(callLazy) {\n await startSpan(\n {\n name: 'Lazy Route Load',\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'lazy',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callLazy();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.lazy', {});\n }\n },\n );\n },\n });\n },\n };\n}\n\nfunction updateRootSpanWithRoute(method: string, pattern: string | undefined, urlPath: string): void {\n const activeSpan = getActiveSpan();\n if (!activeSpan) return;\n const rootSpan = getRootSpan(activeSpan);\n if (!rootSpan) return;\n\n // Skip update if URL path is invalid (failed to parse)\n if (!urlPath || urlPath === '<unknown>') {\n DEBUG_BUILD && debug.warn('Cannot update span with invalid URL path:', urlPath);\n return;\n }\n\n const hasPattern = !!pattern;\n const routeName = hasPattern ? normalizeRoutePath(pattern) || urlPath : urlPath;\n\n const transactionName = `${method} ${routeName}`;\n\n const client = getClient();\n // With span streaming, span names have to be low cardinality, so we can't fall back to the URL path.\n const isUnparameterizedStreamedSpan = !hasPattern && !!client && hasSpanStreamingEnabled(client);\n updateSpanName(\n rootSpan,\n isUnparameterizedStreamedSpan ? method.toUpperCase() || HTTP_SPAN_NAME_FALLBACK : transactionName,\n );\n rootSpan.setAttributes({\n [HTTP_ROUTE]: routeName,\n [SENTRY_SEGMENT_NAME_SOURCE]: hasPattern ? 'route' : 'url',\n });\n\n // Also update the scope's transaction name so errors captured during this request\n // have the correct transaction name (not the initial placeholder like \"GET *\")\n getCurrentScope().setTransactionName(transactionName);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"createServerInstrumentation.js","sources":["../../../src/server/createServerInstrumentation.ts"],"sourcesContent":["import {\n SENTRY_SEGMENT_NAME_SOURCE,\n CODE_FUNCTION_NAME,\n HTTP_REQUEST_METHOD,\n HTTP_ROUTE,\n SENTRY_OP,\n URL_FULL,\n URL_PATH,\n} from '@sentry/conventions/attributes';\nimport { FUNCTION, HTTP_SERVER, MIDDLEWARE } from '@sentry/conventions/op';\nimport {\n debug,\n getActiveSpan,\n getClient,\n getCurrentScope,\n getRootSpan,\n hasSpanStreamingEnabled,\n HTTP_SPAN_NAME_FALLBACK,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SPAN_STATUS_ERROR,\n startSpan,\n updateSpanName,\n filterCollectedUrl,\n} from '@sentry/core';\nimport { flushIfServerless } from '@sentry/core/server';\nimport type { ServerInstrumentation } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport { captureInstrumentationError, getPathFromRequest, getPattern, normalizeRoutePath } from '../common/utils';\nimport { getMiddlewareName } from './serverBuild';\nimport { markInstrumentationApiUsed } from './serverGlobals';\n\n// Per-request middleware counters, keyed by the request's root span (the one transaction all of a\n// request's middlewares run under). The root span is the same instance across those middleware hooks\n// whether or not a Sentry OpenTelemetry tracer provider is set up, unlike the OTel context the counter\n// used to live on (which does not propagate without a provider).\nconst middlewareCountersByRootSpan = new WeakMap<object, Record<string, number>>();\n\n// Re-export for backward compatibility and external use\nexport { isInstrumentationApiUsed } from './serverGlobals';\n\n/**\n * Options for creating Sentry server instrumentation.\n */\nexport interface CreateSentryServerInstrumentationOptions {\n /**\n * Whether to capture errors from loaders/actions automatically.\n * @default true\n */\n captureErrors?: boolean;\n}\n\n/**\n * Creates a Sentry server instrumentation for React Router's instrumentation API.\n */\nexport function createSentryServerInstrumentation(\n options: CreateSentryServerInstrumentationOptions = {},\n): ServerInstrumentation {\n const { captureErrors = true } = options;\n\n DEBUG_BUILD && debug.log('React Router server instrumentation created.');\n\n return {\n handler(handler) {\n // Mark the instrumentation API active only when React Router actually invokes this\n markInstrumentationApiUsed();\n handler.instrument({\n async request(handleRequest, info) {\n const pathname = getPathFromRequest(info.request);\n const activeSpan = getActiveSpan();\n const existingRootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;\n\n const client = getClient();\n // With span streaming, span names have to be low cardinality, so we can't fall back to the URL\n // path. `updateRootSpanWithRoute` renames the span once React Router matches a route.\n const unparameterizedName =\n client && hasSpanStreamingEnabled(client)\n ? info.request.method?.toUpperCase() || HTTP_SPAN_NAME_FALLBACK\n : `${info.request.method} ${pathname}`;\n\n if (existingRootSpan) {\n updateSpanName(existingRootSpan, unparameterizedName);\n existingRootSpan.setAttributes({\n [SENTRY_OP]: HTTP_SERVER,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.instrumentation_api',\n [SENTRY_SEGMENT_NAME_SOURCE]: 'url',\n [URL_FULL]: filterCollectedUrl(info.request.url),\n [URL_PATH]: pathname,\n });\n\n try {\n const result = await handleRequest();\n if (result.status === 'error' && result.error instanceof Error) {\n existingRootSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.request_handler', {\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_FULL]: pathname,\n });\n }\n } finally {\n await flushIfServerless();\n }\n } else {\n await startSpan(\n {\n name: unparameterizedName,\n attributes: {\n [SENTRY_OP]: HTTP_SERVER,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.instrumentation_api',\n [SENTRY_SEGMENT_NAME_SOURCE]: 'url',\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_PATH]: pathname,\n [URL_FULL]: filterCollectedUrl(info.request.url),\n },\n },\n async span => {\n try {\n const result = await handleRequest();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.request_handler', {\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_FULL]: pathname,\n });\n }\n } finally {\n await flushIfServerless();\n }\n },\n );\n }\n },\n });\n },\n\n route(route) {\n // Also mark active here, in case route registration runs (mirrors the handler callback above).\n markInstrumentationApiUsed();\n const routeId = route.id;\n\n route.instrument({\n async loader(callLoader, info) {\n const urlPath = getPathFromRequest(info.request);\n const pattern = getPattern(info);\n const routePattern = normalizeRoutePath(pattern) || urlPath;\n updateRootSpanWithRoute(info.request.method, pattern, urlPath);\n\n await startSpan(\n {\n name: routePattern,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'loader',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callLoader();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.loader', {\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async action(callAction, info) {\n const urlPath = getPathFromRequest(info.request);\n const pattern = getPattern(info);\n const routePattern = normalizeRoutePath(pattern) || urlPath;\n updateRootSpanWithRoute(info.request.method, pattern, urlPath);\n\n await startSpan(\n {\n name: routePattern,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'action',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callAction();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.action', {\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async middleware(callMiddleware, info) {\n const urlPath = getPathFromRequest(info.request);\n const pattern = getPattern(info);\n const routePattern = normalizeRoutePath(pattern) || urlPath;\n\n updateRootSpanWithRoute(info.request.method, pattern, urlPath);\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;\n let middlewareIndex = 0;\n if (rootSpan) {\n let counters = middlewareCountersByRootSpan.get(rootSpan);\n if (!counters) {\n counters = {};\n middlewareCountersByRootSpan.set(rootSpan, counters);\n }\n middlewareIndex = counters[routeId] ?? 0;\n counters[routeId] = middlewareIndex + 1;\n }\n\n const middlewareName = getMiddlewareName(routeId, middlewareIndex);\n\n await startSpan(\n {\n name: `middleware ${middlewareName || routeId}`,\n attributes: {\n [SENTRY_OP]: MIDDLEWARE,\n [CODE_FUNCTION_NAME]: 'middleware',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n 'react_router.route.id': routeId,\n [HTTP_ROUTE]: routePattern,\n ...(middlewareName && { 'react_router.middleware.name': middlewareName }),\n 'react_router.middleware.index': middlewareIndex,\n },\n },\n async span => {\n const result = await callMiddleware();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.middleware', {\n [HTTP_REQUEST_METHOD]: info.request.method,\n [URL_FULL]: urlPath,\n });\n }\n },\n );\n },\n\n async lazy(callLazy) {\n await startSpan(\n {\n name: 'Lazy Route Load',\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'lazy',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callLazy();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.lazy', {});\n }\n },\n );\n },\n });\n },\n };\n}\n\nfunction updateRootSpanWithRoute(method: string, pattern: string | undefined, urlPath: string): void {\n const activeSpan = getActiveSpan();\n if (!activeSpan) return;\n const rootSpan = getRootSpan(activeSpan);\n if (!rootSpan) return;\n\n // Skip update if URL path is invalid (failed to parse)\n if (!urlPath || urlPath === '<unknown>') {\n DEBUG_BUILD && debug.warn('Cannot update span with invalid URL path:', urlPath);\n return;\n }\n\n const hasPattern = !!pattern;\n const routeName = hasPattern ? normalizeRoutePath(pattern) || urlPath : urlPath;\n\n const transactionName = `${method} ${routeName}`;\n\n const client = getClient();\n // With span streaming, span names have to be low cardinality, so we can't fall back to the URL path.\n const isUnparameterizedStreamedSpan = !hasPattern && !!client && hasSpanStreamingEnabled(client);\n updateSpanName(\n rootSpan,\n isUnparameterizedStreamedSpan ? method.toUpperCase() || HTTP_SPAN_NAME_FALLBACK : transactionName,\n );\n rootSpan.setAttributes({\n [HTTP_ROUTE]: routeName,\n [SENTRY_SEGMENT_NAME_SOURCE]: hasPattern ? 'route' : 'url',\n });\n\n // Also update the scope's transaction name so errors captured during this request\n // have the correct transaction name (not the initial placeholder like \"GET *\")\n getCurrentScope().setTransactionName(transactionName);\n}\n"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { SENTRY_SEGMENT_NAME_SOURCE, HTTP_ROUTE } from '@sentry/conventions/attributes';
2
- import { getActiveSpan, getRootSpan, updateSpanName, getCurrentScope, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, flushIfServerless } from '@sentry/core';
2
+ import { getActiveSpan, getRootSpan, updateSpanName, getCurrentScope, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core';
3
+ import { flushIfServerless } from '@sentry/core/server';
3
4
  import { isInstrumentationApiUsed } from './serverGlobals.js';
4
5
 
5
6
  function wrapSentryHandleRequest(originalHandle) {
@@ -1 +1 @@
1
- {"version":3,"file":"wrapSentryHandleRequest.js","sources":["../../../src/server/wrapSentryHandleRequest.ts"],"sourcesContent":["import { SENTRY_SEGMENT_NAME_SOURCE, HTTP_ROUTE } from '@sentry/conventions/attributes';\nimport {\n flushIfServerless,\n getActiveSpan,\n getCurrentScope,\n getRootSpan,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n updateSpanName,\n} from '@sentry/core';\nimport type { AppLoadContext, EntryContext, RouterContextProvider } from 'react-router';\nimport { isInstrumentationApiUsed } from './serverGlobals';\n\ntype OriginalHandleRequestWithoutMiddleware = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n) => Promise<unknown>;\n\ntype OriginalHandleRequestWithMiddleware = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: RouterContextProvider,\n) => Promise<unknown>;\n\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithoutMiddleware,\n): OriginalHandleRequestWithoutMiddleware;\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithMiddleware,\n): OriginalHandleRequestWithMiddleware;\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithoutMiddleware | OriginalHandleRequestWithMiddleware,\n): OriginalHandleRequestWithoutMiddleware | OriginalHandleRequestWithMiddleware {\n return async function sentryInstrumentedHandleRequest(\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext | RouterContextProvider,\n ) {\n const parameterizedPath =\n routerContext?.staticHandlerContext?.matches?.[routerContext.staticHandlerContext.matches.length - 1]?.route.path;\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;\n\n if (parameterizedPath && rootSpan) {\n // Normalize route name - avoid \"//\" for root routes\n const routeName = parameterizedPath.startsWith('/') ? parameterizedPath : `/${parameterizedPath}`;\n\n const transactionName = `${request.method} ${routeName}`;\n\n updateSpanName(rootSpan, transactionName);\n getCurrentScope().setTransactionName(transactionName);\n\n // Set route attributes - acts as fallback for lazy-only routes when using instrumentation API\n // Don't override origin when instrumentation API is used (preserve instrumentation_api origin)\n if (isInstrumentationApiUsed()) {\n rootSpan.setAttributes({\n [HTTP_ROUTE]: routeName,\n [SENTRY_SEGMENT_NAME_SOURCE]: 'route',\n });\n } else {\n rootSpan.setAttributes({\n [HTTP_ROUTE]: routeName,\n [SENTRY_SEGMENT_NAME_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.request_handler',\n });\n }\n }\n\n try {\n // Type guard to call the correct overload based on loadContext type\n if (isRouterContextProvider(loadContext)) {\n // loadContext is RouterContextProvider\n return await (originalHandle as OriginalHandleRequestWithMiddleware)(\n request,\n responseStatusCode,\n responseHeaders,\n routerContext,\n loadContext,\n );\n } else {\n // loadContext is AppLoadContext\n return await (originalHandle as OriginalHandleRequestWithoutMiddleware)(\n request,\n responseStatusCode,\n responseHeaders,\n routerContext,\n loadContext,\n );\n }\n } finally {\n await flushIfServerless();\n }\n\n /**\n * Helper type guard to determine if the context is a RouterContextProvider.\n *\n * @param ctx - The context to check\n * @returns True if the context is a RouterContextProvider\n */\n function isRouterContextProvider(ctx: AppLoadContext | RouterContextProvider): ctx is RouterContextProvider {\n return typeof (ctx as RouterContextProvider)?.get === 'function';\n }\n };\n}\n"],"names":[],"mappings":";;;;AAoDO,SAAS,wBACd,cAAA,EAC8E;AAC9E,EAAA,OAAO,eAAe,+BAAA,CACpB,OAAA,EACA,kBAAA,EACA,eAAA,EACA,eACA,WAAA,EACA;AACA,IAAA,MAAM,iBAAA,GACJ,aAAA,EAAe,oBAAA,EAAsB,OAAA,GAAU,aAAA,CAAc,qBAAqB,OAAA,CAAQ,MAAA,GAAS,CAAC,CAAA,EAAG,KAAA,CAAM,IAAA;AAE/G,IAAA,MAAM,aAAa,aAAA,EAAc;AACjC,IAAA,MAAM,QAAA,GAAW,UAAA,GAAa,WAAA,CAAY,UAAU,CAAA,GAAI,MAAA;AAExD,IAAA,IAAI,qBAAqB,QAAA,EAAU;AAEjC,MAAA,MAAM,YAAY,iBAAA,CAAkB,UAAA,CAAW,GAAG,CAAA,GAAI,iBAAA,GAAoB,IAAI,iBAAiB,CAAA,CAAA;AAE/F,MAAA,MAAM,eAAA,GAAkB,CAAA,EAAG,OAAA,CAAQ,MAAM,IAAI,SAAS,CAAA,CAAA;AAEtD,MAAA,cAAA,CAAe,UAAU,eAAe,CAAA;AACxC,MAAA,eAAA,EAAgB,CAAE,mBAAmB,eAAe,CAAA;AAIpD,MAAA,IAAI,0BAAyB,EAAG;AAC9B,QAAA,QAAA,CAAS,aAAA,CAAc;AAAA,UACrB,CAAC,UAAU,GAAG,SAAA;AAAA,UACd,CAAC,0BAA0B,GAAG;AAAA,SAC/B,CAAA;AAAA,MACH,CAAA,MAAO;AACL,QAAA,QAAA,CAAS,aAAA,CAAc;AAAA,UACrB,CAAC,UAAU,GAAG,SAAA;AAAA,UACd,CAAC,0BAA0B,GAAG,OAAA;AAAA,UAC9B,CAAC,gCAAgC,GAAG;AAAA,SACrC,CAAA;AAAA,MACH;AAAA,IACF;AAEA,IAAA,IAAI;AAEF,MAAA,IAAI,uBAAA,CAAwB,WAAW,CAAA,EAAG;AAExC,QAAA,OAAO,MAAO,cAAA;AAAA,UACZ,OAAA;AAAA,UACA,kBAAA;AAAA,UACA,eAAA;AAAA,UACA,aAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF,CAAA,MAAO;AAEL,QAAA,OAAO,MAAO,cAAA;AAAA,UACZ,OAAA;AAAA,UACA,kBAAA;AAAA,UACA,eAAA;AAAA,UACA,aAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF;AAAA,IACF,CAAA,SAAE;AACA,MAAA,MAAM,iBAAA,EAAkB;AAAA,IAC1B;AAQA,IAAA,SAAS,wBAAwB,GAAA,EAA2E;AAC1G,MAAA,OAAO,OAAQ,KAA+B,GAAA,KAAQ,UAAA;AAAA,IACxD;AAAA,EACF,CAAA;AACF;;;;"}
1
+ {"version":3,"file":"wrapSentryHandleRequest.js","sources":["../../../src/server/wrapSentryHandleRequest.ts"],"sourcesContent":["import { SENTRY_SEGMENT_NAME_SOURCE, HTTP_ROUTE } from '@sentry/conventions/attributes';\nimport {\n getActiveSpan,\n getCurrentScope,\n getRootSpan,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n updateSpanName,\n} from '@sentry/core';\nimport { flushIfServerless } from '@sentry/core/server';\nimport type { AppLoadContext, EntryContext, RouterContextProvider } from 'react-router';\nimport { isInstrumentationApiUsed } from './serverGlobals';\n\ntype OriginalHandleRequestWithoutMiddleware = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n) => Promise<unknown>;\n\ntype OriginalHandleRequestWithMiddleware = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: RouterContextProvider,\n) => Promise<unknown>;\n\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithoutMiddleware,\n): OriginalHandleRequestWithoutMiddleware;\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithMiddleware,\n): OriginalHandleRequestWithMiddleware;\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(\n originalHandle: OriginalHandleRequestWithoutMiddleware | OriginalHandleRequestWithMiddleware,\n): OriginalHandleRequestWithoutMiddleware | OriginalHandleRequestWithMiddleware {\n return async function sentryInstrumentedHandleRequest(\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext | RouterContextProvider,\n ) {\n const parameterizedPath =\n routerContext?.staticHandlerContext?.matches?.[routerContext.staticHandlerContext.matches.length - 1]?.route.path;\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;\n\n if (parameterizedPath && rootSpan) {\n // Normalize route name - avoid \"//\" for root routes\n const routeName = parameterizedPath.startsWith('/') ? parameterizedPath : `/${parameterizedPath}`;\n\n const transactionName = `${request.method} ${routeName}`;\n\n updateSpanName(rootSpan, transactionName);\n getCurrentScope().setTransactionName(transactionName);\n\n // Set route attributes - acts as fallback for lazy-only routes when using instrumentation API\n // Don't override origin when instrumentation API is used (preserve instrumentation_api origin)\n if (isInstrumentationApiUsed()) {\n rootSpan.setAttributes({\n [HTTP_ROUTE]: routeName,\n [SENTRY_SEGMENT_NAME_SOURCE]: 'route',\n });\n } else {\n rootSpan.setAttributes({\n [HTTP_ROUTE]: routeName,\n [SENTRY_SEGMENT_NAME_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.request_handler',\n });\n }\n }\n\n try {\n // Type guard to call the correct overload based on loadContext type\n if (isRouterContextProvider(loadContext)) {\n // loadContext is RouterContextProvider\n return await (originalHandle as OriginalHandleRequestWithMiddleware)(\n request,\n responseStatusCode,\n responseHeaders,\n routerContext,\n loadContext,\n );\n } else {\n // loadContext is AppLoadContext\n return await (originalHandle as OriginalHandleRequestWithoutMiddleware)(\n request,\n responseStatusCode,\n responseHeaders,\n routerContext,\n loadContext,\n );\n }\n } finally {\n await flushIfServerless();\n }\n\n /**\n * Helper type guard to determine if the context is a RouterContextProvider.\n *\n * @param ctx - The context to check\n * @returns True if the context is a RouterContextProvider\n */\n function isRouterContextProvider(ctx: AppLoadContext | RouterContextProvider): ctx is RouterContextProvider {\n return typeof (ctx as RouterContextProvider)?.get === 'function';\n }\n };\n}\n"],"names":[],"mappings":";;;;;AAoDO,SAAS,wBACd,cAAA,EAC8E;AAC9E,EAAA,OAAO,eAAe,+BAAA,CACpB,OAAA,EACA,kBAAA,EACA,eAAA,EACA,eACA,WAAA,EACA;AACA,IAAA,MAAM,iBAAA,GACJ,aAAA,EAAe,oBAAA,EAAsB,OAAA,GAAU,aAAA,CAAc,qBAAqB,OAAA,CAAQ,MAAA,GAAS,CAAC,CAAA,EAAG,KAAA,CAAM,IAAA;AAE/G,IAAA,MAAM,aAAa,aAAA,EAAc;AACjC,IAAA,MAAM,QAAA,GAAW,UAAA,GAAa,WAAA,CAAY,UAAU,CAAA,GAAI,MAAA;AAExD,IAAA,IAAI,qBAAqB,QAAA,EAAU;AAEjC,MAAA,MAAM,YAAY,iBAAA,CAAkB,UAAA,CAAW,GAAG,CAAA,GAAI,iBAAA,GAAoB,IAAI,iBAAiB,CAAA,CAAA;AAE/F,MAAA,MAAM,eAAA,GAAkB,CAAA,EAAG,OAAA,CAAQ,MAAM,IAAI,SAAS,CAAA,CAAA;AAEtD,MAAA,cAAA,CAAe,UAAU,eAAe,CAAA;AACxC,MAAA,eAAA,EAAgB,CAAE,mBAAmB,eAAe,CAAA;AAIpD,MAAA,IAAI,0BAAyB,EAAG;AAC9B,QAAA,QAAA,CAAS,aAAA,CAAc;AAAA,UACrB,CAAC,UAAU,GAAG,SAAA;AAAA,UACd,CAAC,0BAA0B,GAAG;AAAA,SAC/B,CAAA;AAAA,MACH,CAAA,MAAO;AACL,QAAA,QAAA,CAAS,aAAA,CAAc;AAAA,UACrB,CAAC,UAAU,GAAG,SAAA;AAAA,UACd,CAAC,0BAA0B,GAAG,OAAA;AAAA,UAC9B,CAAC,gCAAgC,GAAG;AAAA,SACrC,CAAA;AAAA,MACH;AAAA,IACF;AAEA,IAAA,IAAI;AAEF,MAAA,IAAI,uBAAA,CAAwB,WAAW,CAAA,EAAG;AAExC,QAAA,OAAO,MAAO,cAAA;AAAA,UACZ,OAAA;AAAA,UACA,kBAAA;AAAA,UACA,eAAA;AAAA,UACA,aAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF,CAAA,MAAO;AAEL,QAAA,OAAO,MAAO,cAAA;AAAA,UACZ,OAAA;AAAA,UACA,kBAAA;AAAA,UACA,eAAA;AAAA,UACA,aAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF;AAAA,IACF,CAAA,SAAE;AACA,MAAA,MAAM,iBAAA,EAAkB;AAAA,IAC1B;AAQA,IAAA,SAAS,wBAAwB,GAAA,EAA2E;AAC1G,MAAA,OAAO,OAAQ,KAA+B,GAAA,KAAQ,UAAA;AAAA,IACxD;AAAA,EACF,CAAA;AACF;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"createClientInstrumentation.d.ts","sourceRoot":"","sources":["../../../src/client/createClientInstrumentation.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAuC1D;;GAEG;AACH,MAAM,WAAW,wCAAwC;IACvD;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,OAAO,GAAE,wCAA6C,GACrD,qBAAqB,CA6SvB;AA2BD;;GAEG;AACH,wBAAgB,8BAA8B,IAAI,OAAO,CAExD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C"}
1
+ {"version":3,"file":"createClientInstrumentation.d.ts","sourceRoot":"","sources":["../../../src/client/createClientInstrumentation.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAuC1D;;GAEG;AACH,MAAM,WAAW,wCAAwC;IACvD;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,OAAO,GAAE,wCAA6C,GACrD,qBAAqB,CA6SvB;AA2BD;;GAEG;AACH,wBAAgB,8BAA8B,IAAI,OAAO,CAExD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C"}
@@ -7,7 +7,6 @@ export * from './server';
7
7
  export declare function init(options: Options | clientSdk.BrowserOptions | serverSdk.NodeOptions): void;
8
8
  export declare const contextLinesIntegration: typeof clientSdk.contextLinesIntegration;
9
9
  export declare const linkedErrorsIntegration: typeof clientSdk.linkedErrorsIntegration;
10
- export declare const spanStreamingIntegration: typeof clientSdk.spanStreamingIntegration;
11
10
  export declare const startSpan: typeof clientSdk.startSpan;
12
11
  export declare const startSpanManual: typeof clientSdk.startSpanManual;
13
12
  export declare const startInactiveSpan: typeof clientSdk.startInactiveSpan;
@@ -1 +1 @@
1
- {"version":3,"file":"index.types.d.ts","sourceRoot":"","sources":["../../src/index.types.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,KAAK,KAAK,SAAS,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,KAAK,SAAS,MAAM,UAAU,CAAC;AAG3C,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AAEzB,0CAA0C;AAC1C,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC,cAAc,GAAG,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC;AAExG,MAAM,CAAC,OAAO,CAAC,MAAM,uBAAuB,EAAE,OAAO,SAAS,CAAC,uBAAuB,CAAC;AACvF,MAAM,CAAC,OAAO,CAAC,MAAM,uBAAuB,EAAE,OAAO,SAAS,CAAC,uBAAuB,CAAC;AACvF,MAAM,CAAC,OAAO,CAAC,MAAM,wBAAwB,EAAE,OAAO,SAAS,CAAC,wBAAwB,CAAC;AACzF,MAAM,CAAC,OAAO,CAAC,MAAM,SAAS,EAAE,OAAO,SAAS,CAAC,SAAS,CAAC;AAC3D,MAAM,CAAC,OAAO,CAAC,MAAM,eAAe,EAAE,OAAO,SAAS,CAAC,eAAe,CAAC;AACvE,MAAM,CAAC,OAAO,CAAC,MAAM,iBAAiB,EAAE,OAAO,SAAS,CAAC,iBAAiB,CAAC;AAC3E,MAAM,CAAC,OAAO,CAAC,MAAM,cAAc,EAAE,OAAO,SAAS,CAAC,cAAc,CAAC;AAErE,MAAM,CAAC,OAAO,CAAC,MAAM,gBAAgB,EAAE,OAAO,SAAS,CAAC,gBAAgB,CAAC;AACzE,MAAM,CAAC,OAAO,CAAC,MAAM,kBAAkB,EAAE,WAAW,CAAC;AACrD,MAAM,CAAC,OAAO,CAAC,MAAM,sBAAsB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,WAAW,EAAE,CAAC;AAEjF,MAAM,CAAC,OAAO,CAAC,MAAM,MAAM,EAAE,OAAO,SAAS,CAAC,MAAM,GAAG,OAAO,SAAS,CAAC,MAAM,CAAC;AAE/E,MAAM,CAAC,OAAO,CAAC,MAAM,qBAAqB,EAAE,OAAO,SAAS,CAAC,qBAAqB,CAAC;AACnF,MAAM,CAAC,OAAO,CAAC,MAAM,uBAAuB,EAAE,OAAO,SAAS,CAAC,uBAAuB,CAAC;AACvF,MAAM,CAAC,OAAO,CAAC,MAAM,gCAAgC,EAAE,OAAO,SAAS,CAAC,gCAAgC,CAAC;AACzG,MAAM,CAAC,OAAO,CAAC,MAAM,sBAAsB,EAAE,OAAO,SAAS,CAAC,sBAAsB,CAAC;AACrF,MAAM,CAAC,OAAO,CAAC,MAAM,0BAA0B,EAAE,OAAO,SAAS,CAAC,0BAA0B,CAAC;AAC7F,MAAM,CAAC,OAAO,CAAC,MAAM,kBAAkB,EAAE,OAAO,SAAS,CAAC,kBAAkB,CAAC;AAC7E,MAAM,CAAC,OAAO,CAAC,MAAM,kBAAkB,EAAE,OAAO,SAAS,CAAC,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.types.d.ts","sourceRoot":"","sources":["../../src/index.types.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,KAAK,KAAK,SAAS,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,KAAK,SAAS,MAAM,UAAU,CAAC;AAG3C,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AAEzB,0CAA0C;AAC1C,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC,cAAc,GAAG,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC;AAExG,MAAM,CAAC,OAAO,CAAC,MAAM,uBAAuB,EAAE,OAAO,SAAS,CAAC,uBAAuB,CAAC;AACvF,MAAM,CAAC,OAAO,CAAC,MAAM,uBAAuB,EAAE,OAAO,SAAS,CAAC,uBAAuB,CAAC;AACvF,MAAM,CAAC,OAAO,CAAC,MAAM,SAAS,EAAE,OAAO,SAAS,CAAC,SAAS,CAAC;AAC3D,MAAM,CAAC,OAAO,CAAC,MAAM,eAAe,EAAE,OAAO,SAAS,CAAC,eAAe,CAAC;AACvE,MAAM,CAAC,OAAO,CAAC,MAAM,iBAAiB,EAAE,OAAO,SAAS,CAAC,iBAAiB,CAAC;AAC3E,MAAM,CAAC,OAAO,CAAC,MAAM,cAAc,EAAE,OAAO,SAAS,CAAC,cAAc,CAAC;AAErE,MAAM,CAAC,OAAO,CAAC,MAAM,gBAAgB,EAAE,OAAO,SAAS,CAAC,gBAAgB,CAAC;AACzE,MAAM,CAAC,OAAO,CAAC,MAAM,kBAAkB,EAAE,WAAW,CAAC;AACrD,MAAM,CAAC,OAAO,CAAC,MAAM,sBAAsB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,WAAW,EAAE,CAAC;AAEjF,MAAM,CAAC,OAAO,CAAC,MAAM,MAAM,EAAE,OAAO,SAAS,CAAC,MAAM,GAAG,OAAO,SAAS,CAAC,MAAM,CAAC;AAE/E,MAAM,CAAC,OAAO,CAAC,MAAM,qBAAqB,EAAE,OAAO,SAAS,CAAC,qBAAqB,CAAC;AACnF,MAAM,CAAC,OAAO,CAAC,MAAM,uBAAuB,EAAE,OAAO,SAAS,CAAC,uBAAuB,CAAC;AACvF,MAAM,CAAC,OAAO,CAAC,MAAM,gCAAgC,EAAE,OAAO,SAAS,CAAC,gCAAgC,CAAC;AACzG,MAAM,CAAC,OAAO,CAAC,MAAM,sBAAsB,EAAE,OAAO,SAAS,CAAC,sBAAsB,CAAC;AACrF,MAAM,CAAC,OAAO,CAAC,MAAM,0BAA0B,EAAE,OAAO,SAAS,CAAC,0BAA0B,CAAC;AAC7F,MAAM,CAAC,OAAO,CAAC,MAAM,kBAAkB,EAAE,OAAO,SAAS,CAAC,kBAAkB,CAAC;AAC7E,MAAM,CAAC,OAAO,CAAC,MAAM,kBAAkB,EAAE,OAAO,SAAS,CAAC,kBAAkB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"createSentryHandleError.d.ts","sourceRoot":"","sources":["../../../src/server/createSentryHandleError.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAExD,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,SAAiB,EAAE,EAAE,wBAAwB,GAAG,mBAAmB,CAuB5G"}
1
+ {"version":3,"file":"createSentryHandleError.d.ts","sourceRoot":"","sources":["../../../src/server/createSentryHandleError.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAExD,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,SAAiB,EAAE,EAAE,wBAAwB,GAAG,mBAAmB,CAuB5G"}
@@ -1 +1 @@
1
- {"version":3,"file":"createServerInstrumentation.d.ts","sourceRoot":"","sources":["../../../src/server/createServerInstrumentation.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAa1D,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,wCAAwC;IACvD;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,OAAO,GAAE,wCAA6C,GACrD,qBAAqB,CAmNvB"}
1
+ {"version":3,"file":"createServerInstrumentation.d.ts","sourceRoot":"","sources":["../../../src/server/createServerInstrumentation.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAa1D,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,wCAAwC;IACvD;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,OAAO,GAAE,wCAA6C,GACrD,qBAAqB,CAkNvB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/react-router",
3
- "version": "11.0.0-alpha.2",
3
+ "version": "11.0.0-beta.0",
4
4
  "description": "Official Sentry SDK for React Router (Framework)",
5
5
  "repository": "git://github.com/getsentry/sentry-javascript.git",
6
6
  "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/react-router",
@@ -51,13 +51,14 @@
51
51
  },
52
52
  "dependencies": {
53
53
  "@opentelemetry/api": "^1.9.1",
54
- "@sentry/browser": "11.0.0-alpha.2",
54
+ "@sentry/browser": "11.0.0-beta.0",
55
55
  "@sentry/conventions": "^0.20.0",
56
- "@sentry/core": "11.0.0-alpha.2",
57
- "@sentry/node": "11.0.0-alpha.2",
58
- "@sentry/react": "11.0.0-alpha.2",
59
- "@sentry/server-utils": "11.0.0-alpha.2",
60
- "@sentry/bundler-plugins": "11.0.0-alpha.2",
56
+ "@sentry/core": "11.0.0-beta.0",
57
+ "@sentry/node": "11.0.0-beta.0",
58
+ "@sentry/react": "11.0.0-beta.0",
59
+ "@sentry/server-runtime-injection": "11.0.0-beta.0",
60
+ "@sentry/server-utils": "11.0.0-beta.0",
61
+ "@sentry/bundler-plugins": "11.0.0-beta.0",
61
62
  "glob": "^13.0.6",
62
63
  "sentry": "^0.44.0"
63
64
  },