@sentry/react-router 10.53.0 → 10.54.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 (119) hide show
  1. package/build/cjs/client/createClientInstrumentation.js +104 -175
  2. package/build/cjs/client/createClientInstrumentation.js.map +1 -1
  3. package/build/cjs/client/hydratedRouter.js +27 -74
  4. package/build/cjs/client/hydratedRouter.js.map +1 -1
  5. package/build/cjs/client/sdk.js +5 -16
  6. package/build/cjs/client/sdk.js.map +1 -1
  7. package/build/cjs/client/sentryOnError.js +4 -27
  8. package/build/cjs/client/sentryOnError.js.map +1 -1
  9. package/build/cjs/client/tracingIntegration.js +4 -18
  10. package/build/cjs/client/tracingIntegration.js.map +1 -1
  11. package/build/cjs/client/utils.js +5 -17
  12. package/build/cjs/client/utils.js.map +1 -1
  13. package/build/cjs/cloudflare/index.js +2 -15
  14. package/build/cjs/cloudflare/index.js.map +1 -1
  15. package/build/cjs/common/debug-build.js +0 -5
  16. package/build/cjs/common/debug-build.js.map +1 -1
  17. package/build/cjs/common/utils.js +8 -33
  18. package/build/cjs/common/utils.js.map +1 -1
  19. package/build/cjs/server/createSentryHandleError.js +4 -13
  20. package/build/cjs/server/createSentryHandleError.js.map +1 -1
  21. package/build/cjs/server/createSentryHandleRequest.js +14 -49
  22. package/build/cjs/server/createSentryHandleRequest.js.map +1 -1
  23. package/build/cjs/server/createServerInstrumentation.js +76 -114
  24. package/build/cjs/server/createServerInstrumentation.js.map +1 -1
  25. package/build/cjs/server/getMetaTagTransformer.js +2 -8
  26. package/build/cjs/server/getMetaTagTransformer.js.map +1 -1
  27. package/build/cjs/server/instrumentation/reactRouter.js +21 -47
  28. package/build/cjs/server/instrumentation/reactRouter.js.map +1 -1
  29. package/build/cjs/server/instrumentation/util.js +5 -41
  30. package/build/cjs/server/instrumentation/util.js.map +1 -1
  31. package/build/cjs/server/integration/lowQualityTransactionsFilterIntegration.js +5 -12
  32. package/build/cjs/server/integration/lowQualityTransactionsFilterIntegration.js.map +1 -1
  33. package/build/cjs/server/integration/reactRouterServer.js +10 -42
  34. package/build/cjs/server/integration/reactRouterServer.js.map +1 -1
  35. package/build/cjs/server/sdk.js +6 -20
  36. package/build/cjs/server/sdk.js.map +1 -1
  37. package/build/cjs/server/serverBuild.js +6 -31
  38. package/build/cjs/server/serverBuild.js.map +1 -1
  39. package/build/cjs/server/serverGlobals.js +6 -26
  40. package/build/cjs/server/serverGlobals.js.map +1 -1
  41. package/build/cjs/server/wrapSentryHandleRequest.js +13 -53
  42. package/build/cjs/server/wrapSentryHandleRequest.js.map +1 -1
  43. package/build/cjs/server/wrapServerAction.js +12 -44
  44. package/build/cjs/server/wrapServerAction.js.map +1 -1
  45. package/build/cjs/server/wrapServerLoader.js +12 -44
  46. package/build/cjs/server/wrapServerLoader.js.map +1 -1
  47. package/build/cjs/vite/buildEnd/handleOnBuildEnd.js +38 -72
  48. package/build/cjs/vite/buildEnd/handleOnBuildEnd.js.map +1 -1
  49. package/build/cjs/vite/makeConfigInjectorPlugin.js +4 -12
  50. package/build/cjs/vite/makeConfigInjectorPlugin.js.map +1 -1
  51. package/build/cjs/vite/makeCustomSentryVitePlugins.js +10 -15
  52. package/build/cjs/vite/makeCustomSentryVitePlugins.js.map +1 -1
  53. package/build/cjs/vite/makeEnableSourceMapsPlugin.js +19 -51
  54. package/build/cjs/vite/makeEnableSourceMapsPlugin.js.map +1 -1
  55. package/build/cjs/vite/makeServerBuildCapturePlugin.js +4 -15
  56. package/build/cjs/vite/makeServerBuildCapturePlugin.js.map +1 -1
  57. package/build/cjs/vite/plugin.js +3 -16
  58. package/build/cjs/vite/plugin.js.map +1 -1
  59. package/build/esm/client/createClientInstrumentation.js +104 -175
  60. package/build/esm/client/createClientInstrumentation.js.map +1 -1
  61. package/build/esm/client/hydratedRouter.js +27 -74
  62. package/build/esm/client/hydratedRouter.js.map +1 -1
  63. package/build/esm/client/sdk.js +5 -16
  64. package/build/esm/client/sdk.js.map +1 -1
  65. package/build/esm/client/sentryOnError.js +4 -27
  66. package/build/esm/client/sentryOnError.js.map +1 -1
  67. package/build/esm/client/tracingIntegration.js +4 -18
  68. package/build/esm/client/tracingIntegration.js.map +1 -1
  69. package/build/esm/client/utils.js +5 -17
  70. package/build/esm/client/utils.js.map +1 -1
  71. package/build/esm/cloudflare/index.js +2 -15
  72. package/build/esm/cloudflare/index.js.map +1 -1
  73. package/build/esm/common/debug-build.js +0 -5
  74. package/build/esm/common/debug-build.js.map +1 -1
  75. package/build/esm/common/utils.js +8 -33
  76. package/build/esm/common/utils.js.map +1 -1
  77. package/build/esm/package.json +1 -1
  78. package/build/esm/server/createSentryHandleError.js +4 -13
  79. package/build/esm/server/createSentryHandleError.js.map +1 -1
  80. package/build/esm/server/createSentryHandleRequest.js +14 -49
  81. package/build/esm/server/createSentryHandleRequest.js.map +1 -1
  82. package/build/esm/server/createServerInstrumentation.js +76 -114
  83. package/build/esm/server/createServerInstrumentation.js.map +1 -1
  84. package/build/esm/server/getMetaTagTransformer.js +2 -8
  85. package/build/esm/server/getMetaTagTransformer.js.map +1 -1
  86. package/build/esm/server/instrumentation/reactRouter.js +21 -47
  87. package/build/esm/server/instrumentation/reactRouter.js.map +1 -1
  88. package/build/esm/server/instrumentation/util.js +5 -41
  89. package/build/esm/server/instrumentation/util.js.map +1 -1
  90. package/build/esm/server/integration/lowQualityTransactionsFilterIntegration.js +5 -12
  91. package/build/esm/server/integration/lowQualityTransactionsFilterIntegration.js.map +1 -1
  92. package/build/esm/server/integration/reactRouterServer.js +10 -42
  93. package/build/esm/server/integration/reactRouterServer.js.map +1 -1
  94. package/build/esm/server/sdk.js +6 -20
  95. package/build/esm/server/sdk.js.map +1 -1
  96. package/build/esm/server/serverBuild.js +6 -31
  97. package/build/esm/server/serverBuild.js.map +1 -1
  98. package/build/esm/server/serverGlobals.js +6 -26
  99. package/build/esm/server/serverGlobals.js.map +1 -1
  100. package/build/esm/server/wrapSentryHandleRequest.js +13 -53
  101. package/build/esm/server/wrapSentryHandleRequest.js.map +1 -1
  102. package/build/esm/server/wrapServerAction.js +12 -44
  103. package/build/esm/server/wrapServerAction.js.map +1 -1
  104. package/build/esm/server/wrapServerLoader.js +12 -44
  105. package/build/esm/server/wrapServerLoader.js.map +1 -1
  106. package/build/esm/vite/buildEnd/handleOnBuildEnd.js +38 -72
  107. package/build/esm/vite/buildEnd/handleOnBuildEnd.js.map +1 -1
  108. package/build/esm/vite/makeConfigInjectorPlugin.js +4 -12
  109. package/build/esm/vite/makeConfigInjectorPlugin.js.map +1 -1
  110. package/build/esm/vite/makeCustomSentryVitePlugins.js +10 -15
  111. package/build/esm/vite/makeCustomSentryVitePlugins.js.map +1 -1
  112. package/build/esm/vite/makeEnableSourceMapsPlugin.js +19 -51
  113. package/build/esm/vite/makeEnableSourceMapsPlugin.js.map +1 -1
  114. package/build/esm/vite/makeServerBuildCapturePlugin.js +4 -15
  115. package/build/esm/vite/makeServerBuildCapturePlugin.js.map +1 -1
  116. package/build/esm/vite/plugin.js +3 -16
  117. package/build/esm/vite/plugin.js.map +1 -1
  118. package/build/types/client/hydratedRouter.d.ts.map +1 -1
  119. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../../src/common/utils.ts"],"sourcesContent":["import { captureException, debug } from '@sentry/core';\nimport { DEBUG_BUILD } from './debug-build';\nimport type { InstrumentationResult } from './types';\n\n/**\n * Extracts pathname from request URL.\n * Falls back to '<unknown>' with DEBUG warning if URL cannot be parsed.\n */\nexport function getPathFromRequest(request: { url: string }): string {\n try {\n return new URL(request.url).pathname;\n } catch {\n try {\n // Fallback: use a dummy base URL since we only care about the pathname\n return new URL(request.url, 'http://example.com').pathname;\n } catch (error) {\n DEBUG_BUILD && debug.warn('Failed to parse URL from request:', request.url, error);\n return '<unknown>';\n }\n }\n}\n\n/**\n * Extracts route pattern from instrumentation info.\n * Prefers `pattern` (planned for v8) over `unstable_pattern` (v7.x).\n */\nexport function getPattern(info: { pattern?: string; unstable_pattern?: string }): string | undefined {\n return info.pattern ?? info.unstable_pattern;\n}\n\n/**\n * Normalizes route path by ensuring it starts with a slash.\n * Returns undefined if the input is falsy.\n */\nexport function normalizeRoutePath(pattern?: string): string | undefined {\n if (!pattern) {\n return undefined;\n }\n return pattern.startsWith('/') ? pattern : `/${pattern}`;\n}\n\n/**\n * Captures an error from instrumentation result.\n * Caller must verify result contains an Error before calling.\n */\nexport function captureInstrumentationError(\n result: InstrumentationResult,\n captureErrors: boolean,\n mechanismType: string,\n data: Record<string, string | boolean>,\n): void {\n if (captureErrors) {\n captureException(result.error, {\n mechanism: {\n type: mechanismType,\n handled: false,\n data,\n },\n });\n }\n}\n"],"names":["DEBUG_BUILD","debug","captureException"],"mappings":";;;;;AAIA;AACA;AACA;AACA;AACO,SAAS,kBAAkB,CAAC,OAAO,EAA2B;AACrE,EAAE,IAAI;AACN,IAAI,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ;AACxC,EAAE,EAAE,MAAM;AACV,IAAI,IAAI;AACR;AACA,MAAM,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC,QAAQ;AAChE,IAAI,CAAA,CAAE,OAAO,KAAK,EAAE;AACpB,MAAMA,sBAAA,IAAeC,UAAK,CAAC,IAAI,CAAC,mCAAmC,EAAE,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC;AACxF,MAAM,OAAO,WAAW;AACxB,IAAI;AACJ,EAAE;AACF;;AAEA;AACA;AACA;AACA;AACO,SAAS,UAAU,CAAC,IAAI,EAAuE;AACtG,EAAE,OAAO,IAAI,CAAC,WAAW,IAAI,CAAC,gBAAgB;AAC9C;;AAEA;AACA;AACA;AACA;AACO,SAAS,kBAAkB,CAAC,OAAO,EAA+B;AACzE,EAAE,IAAI,CAAC,OAAO,EAAE;AAChB,IAAI,OAAO,SAAS;AACpB,EAAE;AACF,EAAE,OAAO,OAAO,CAAC,UAAU,CAAC,GAAG,CAAA,GAAI,OAAA,GAAU,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAA,2BAAA;AACA,EAAA,MAAA;AACA,EAAA,aAAA;AACA,EAAA,aAAA;AACA,EAAA,IAAA;AACA,EAAA;AACA,EAAA,IAAA,aAAA,EAAA;AACA,IAAAC,qBAAA,CAAA,MAAA,CAAA,KAAA,EAAA;AACA,MAAA,SAAA,EAAA;AACA,QAAA,IAAA,EAAA,aAAA;AACA,QAAA,OAAA,EAAA,KAAA;AACA,QAAA,IAAA;AACA,OAAA;AACA,KAAA,CAAA;AACA,EAAA;AACA;;;;;;;"}
1
+ {"version":3,"file":"utils.js","sources":["../../../src/common/utils.ts"],"sourcesContent":["import { captureException, debug } from '@sentry/core';\nimport { DEBUG_BUILD } from './debug-build';\nimport type { InstrumentationResult } from './types';\n\n/**\n * Extracts pathname from request URL.\n * Falls back to '<unknown>' with DEBUG warning if URL cannot be parsed.\n */\nexport function getPathFromRequest(request: { url: string }): string {\n try {\n return new URL(request.url).pathname;\n } catch {\n try {\n // Fallback: use a dummy base URL since we only care about the pathname\n return new URL(request.url, 'http://example.com').pathname;\n } catch (error) {\n DEBUG_BUILD && debug.warn('Failed to parse URL from request:', request.url, error);\n return '<unknown>';\n }\n }\n}\n\n/**\n * Extracts route pattern from instrumentation info.\n * Prefers `pattern` (planned for v8) over `unstable_pattern` (v7.x).\n */\nexport function getPattern(info: { pattern?: string; unstable_pattern?: string }): string | undefined {\n return info.pattern ?? info.unstable_pattern;\n}\n\n/**\n * Normalizes route path by ensuring it starts with a slash.\n * Returns undefined if the input is falsy.\n */\nexport function normalizeRoutePath(pattern?: string): string | undefined {\n if (!pattern) {\n return undefined;\n }\n return pattern.startsWith('/') ? pattern : `/${pattern}`;\n}\n\n/**\n * Captures an error from instrumentation result.\n * Caller must verify result contains an Error before calling.\n */\nexport function captureInstrumentationError(\n result: InstrumentationResult,\n captureErrors: boolean,\n mechanismType: string,\n data: Record<string, string | boolean>,\n): void {\n if (captureErrors) {\n captureException(result.error, {\n mechanism: {\n type: mechanismType,\n handled: false,\n data,\n },\n });\n }\n}\n"],"names":["DEBUG_BUILD","debug","captureException"],"mappings":";;;;;AAQO,SAAS,mBAAmB,OAAA,EAAkC;AACnE,EAAA,IAAI;AACF,IAAA,OAAO,IAAI,GAAA,CAAI,OAAA,CAAQ,GAAG,CAAA,CAAE,QAAA;AAAA,EAC9B,CAAA,CAAA,MAAQ;AACN,IAAA,IAAI;AAEF,MAAA,OAAO,IAAI,GAAA,CAAI,OAAA,CAAQ,GAAA,EAAK,oBAAoB,CAAA,CAAE,QAAA;AAAA,IACpD,SAAS,KAAA,EAAO;AACd,MAAAA,sBAAA,IAAeC,UAAA,CAAM,IAAA,CAAK,mCAAA,EAAqC,OAAA,CAAQ,KAAK,KAAK,CAAA;AACjF,MAAA,OAAO,WAAA;AAAA,IACT;AAAA,EACF;AACF;AAMO,SAAS,WAAW,IAAA,EAA2E;AACpG,EAAA,OAAO,IAAA,CAAK,WAAW,IAAA,CAAK,gBAAA;AAC9B;AAMO,SAAS,mBAAmB,OAAA,EAAsC;AACvE,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,OAAO,QAAQ,UAAA,CAAW,GAAG,CAAA,GAAI,OAAA,GAAU,IAAI,OAAO,CAAA,CAAA;AACxD;AAMO,SAAS,2BAAA,CACd,MAAA,EACA,aAAA,EACA,aAAA,EACA,IAAA,EACM;AACN,EAAA,IAAI,aAAA,EAAe;AACjB,IAAAC,qBAAA,CAAiB,OAAO,KAAA,EAAO;AAAA,MAC7B,SAAA,EAAW;AAAA,QACT,IAAA,EAAM,aAAA;AAAA,QACN,OAAA,EAAS,KAAA;AAAA,QACT;AAAA;AACF,KACD,CAAA;AAAA,EACH;AACF;;;;;;;"}
@@ -2,33 +2,24 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const core = require('@sentry/core');
4
4
 
5
- /**
6
- * A complete Sentry-instrumented handleError implementation that handles error reporting
7
- *
8
- * @returns A Sentry-instrumented handleError function
9
- */
10
5
  function createSentryHandleError({ logErrors = false }) {
11
- const handleError = async function handleError(error, args) {
12
- // React Router may abort some interrupted requests, don't report those
6
+ const handleError = async function handleError2(error, args) {
13
7
  if (!args.request.signal.aborted) {
14
8
  core.captureException(error, {
15
9
  mechanism: {
16
- type: 'react-router',
17
- handled: false,
18
- },
10
+ type: "react-router",
11
+ handled: false
12
+ }
19
13
  });
20
14
  if (logErrors) {
21
- // eslint-disable-next-line no-console
22
15
  console.error(error);
23
16
  }
24
17
  try {
25
18
  await core.flushIfServerless();
26
19
  } catch {
27
- // Ignore flush errors to ensure error handling completes gracefully
28
20
  }
29
21
  }
30
22
  };
31
-
32
23
  return handleError;
33
24
  }
34
25
 
@@ -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":["captureException","flushIfServerless"],"mappings":";;;;AAOA;AACA;AACA;AACA;AACA;AACO,SAAS,uBAAuB,CAAC,EAAE,YAAY,KAAA,EAAO,EAAiD;AAC9G,EAAE,MAAM,WAAW,GAAwB,eAAe,WAAW,CAAC,KAAK,EAAE,IAAI,EAAiB;AAClG;AACA,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE;AACtC,MAAMA,qBAAgB,CAAC,KAAK,EAAE;AAC9B,QAAQ,SAAS,EAAE;AACnB,UAAU,IAAI,EAAE,cAAc;AAC9B,UAAU,OAAO,EAAE,KAAK;AACxB,SAAS;AACT,OAAO,CAAC;AACR,MAAM,IAAI,SAAS,EAAE;AACrB;AACA,QAAQ,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;AAC5B,MAAM;AACN,MAAM,IAAI;AACV,QAAQ,MAAMC,sBAAiB,EAAE;AACjC,MAAM,EAAE,MAAM;AACd;AACA,MAAM;AACN,IAAI;AACJ,EAAE,CAAC;;AAEH,EAAE,OAAO,WAAW;AACpB;;;;"}
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;;;;"}
@@ -5,84 +5,49 @@ const stream = require('stream');
5
5
  const getMetaTagTransformer = require('./getMetaTagTransformer.js');
6
6
  const wrapSentryHandleRequest = require('./wrapSentryHandleRequest.js');
7
7
 
8
- /**
9
- * A complete Sentry-instrumented handleRequest implementation that handles both
10
- * route parametrization and trace meta tag injection.
11
- *
12
- * @param options Configuration options
13
- * @returns A Sentry-instrumented handleRequest function
14
- */
15
- function createSentryHandleRequest(
16
- options,
17
- ) {
8
+ function createSentryHandleRequest(options) {
18
9
  const {
19
- streamTimeout = 10000,
10
+ streamTimeout = 1e4,
20
11
  renderToPipeableStream,
21
12
  ServerRouter,
22
13
  createReadableStreamFromReadable,
23
- botRegex = /bot|crawler|spider|googlebot|chrome-lighthouse|baidu|bing|google|yahoo|lighthouse/i,
14
+ botRegex = /bot|crawler|spider|googlebot|chrome-lighthouse|baidu|bing|google|yahoo|lighthouse/i
24
15
  } = options;
25
-
26
- const handleRequest = function handleRequest(
27
- request,
28
- responseStatusCode,
29
- responseHeaders,
30
- routerContext,
31
- _loadContext,
32
- ) {
16
+ const handleRequest = function handleRequest2(request, responseStatusCode, responseHeaders, routerContext, _loadContext) {
33
17
  return new Promise((resolve, reject) => {
34
18
  let shellRendered = false;
35
- const userAgent = request.headers.get('user-agent');
36
-
37
- // Determine if we should use onAllReady or onShellReady
38
- const isBot = typeof userAgent === 'string' && botRegex.test(userAgent);
39
- const isSpaMode = !!(routerContext ).isSpaMode;
40
-
41
- const readyOption = isBot || isSpaMode ? 'onAllReady' : 'onShellReady';
42
-
43
- const { pipe, abort } = renderToPipeableStream(React.default.createElement(ServerRouter, { context: routerContext, url: request.url,} ), {
19
+ const userAgent = request.headers.get("user-agent");
20
+ const isBot = typeof userAgent === "string" && botRegex.test(userAgent);
21
+ const isSpaMode = !!routerContext.isSpaMode;
22
+ const readyOption = isBot || isSpaMode ? "onAllReady" : "onShellReady";
23
+ const { pipe, abort } = renderToPipeableStream(/* @__PURE__ */ React.default.createElement(ServerRouter, { context: routerContext, url: request.url }), {
44
24
  [readyOption]() {
45
25
  shellRendered = true;
46
26
  const body = new stream.PassThrough();
47
-
48
27
  const stream$1 = createReadableStreamFromReadable(body);
49
-
50
- responseHeaders.set('Content-Type', 'text/html');
51
-
28
+ responseHeaders.set("Content-Type", "text/html");
52
29
  resolve(
53
30
  new Response(stream$1, {
54
31
  headers: responseHeaders,
55
- status: responseStatusCode,
56
- }),
32
+ status: responseStatusCode
33
+ })
57
34
  );
58
-
59
- // this injects trace data to the HTML head
60
35
  pipe(getMetaTagTransformer.getMetaTagTransformer(body));
61
36
  },
62
37
  onShellError(error) {
63
38
  reject(error);
64
39
  },
65
40
  onError(error) {
66
- // eslint-disable-next-line no-param-reassign
67
41
  responseStatusCode = 500;
68
- // Log streaming rendering errors from inside the shell. Don't log
69
- // errors encountered during initial shell rendering since they'll
70
- // reject and get logged in handleDocumentRequest.
71
42
  if (shellRendered) {
72
- // eslint-disable-next-line no-console
73
43
  console.error(error);
74
44
  }
75
- },
45
+ }
76
46
  });
77
-
78
- // Abort the rendering stream after the `streamTimeout`
79
47
  setTimeout(abort, streamTimeout);
80
48
  });
81
49
  };
82
-
83
- // Wrap the handle request function for request parametrization
84
- return wrapSentryHandleRequest.wrapSentryHandleRequest(handleRequest )
85
- ;
50
+ return wrapSentryHandleRequest.wrapSentryHandleRequest(handleRequest);
86
51
  }
87
52
 
88
53
  exports.createSentryHandleRequest = createSentryHandleRequest;
@@ -1 +1 @@
1
- {"version":3,"file":"createSentryHandleRequest.js","sources":["../../../src/server/createSentryHandleRequest.tsx"],"sourcesContent":["import type { createReadableStreamFromReadable } from '@react-router/node';\nimport type { ReactNode } from 'react';\nimport React from 'react';\nimport type { AppLoadContext, EntryContext, RouterContextProvider, ServerRouter } from 'react-router';\nimport { PassThrough } from 'stream';\nimport { getMetaTagTransformer } from './getMetaTagTransformer';\nimport { wrapSentryHandleRequest } from './wrapSentryHandleRequest';\n\ntype RenderToPipeableStreamOptions = {\n [key: string]: unknown;\n onShellReady?: () => void;\n onAllReady?: () => void;\n onShellError?: (error: unknown) => void;\n onError?: (error: unknown) => void;\n};\n\ntype RenderToPipeableStreamResult = {\n pipe: (destination: NodeJS.WritableStream) => void;\n abort: () => void;\n};\n\ntype RenderToPipeableStreamFunction = (\n node: ReactNode,\n options: RenderToPipeableStreamOptions,\n) => RenderToPipeableStreamResult;\n\nexport interface SentryHandleRequestOptions {\n /**\n * Timeout in milliseconds after which the rendering stream will be aborted\n * @default 10000\n */\n streamTimeout?: number;\n\n /**\n * React's renderToPipeableStream function from 'react-dom/server'\n */\n renderToPipeableStream: RenderToPipeableStreamFunction;\n\n /**\n * The <ServerRouter /> component from '@react-router/server'\n */\n ServerRouter: typeof ServerRouter;\n\n /**\n * createReadableStreamFromReadable from '@react-router/node'\n */\n createReadableStreamFromReadable: typeof createReadableStreamFromReadable;\n\n /**\n * Regular expression to identify bot user agents\n * @default /bot|crawler|spider|googlebot|chrome-lighthouse|baidu|bing|google|yahoo|lighthouse/i\n */\n botRegex?: RegExp;\n}\n\ntype HandleRequestWithoutMiddleware = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n) => Promise<unknown>;\n\ntype HandleRequestWithMiddleware = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: RouterContextProvider,\n) => Promise<unknown>;\n\n/**\n * A complete Sentry-instrumented handleRequest implementation that handles both\n * route parametrization and trace meta tag injection.\n *\n * @param options Configuration options\n * @returns A Sentry-instrumented handleRequest function\n */\nexport function createSentryHandleRequest(\n options: SentryHandleRequestOptions,\n): HandleRequestWithoutMiddleware & HandleRequestWithMiddleware {\n const {\n streamTimeout = 10000,\n renderToPipeableStream,\n ServerRouter,\n createReadableStreamFromReadable,\n botRegex = /bot|crawler|spider|googlebot|chrome-lighthouse|baidu|bing|google|yahoo|lighthouse/i,\n } = options;\n\n const handleRequest = function handleRequest(\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n _loadContext: AppLoadContext | RouterContextProvider,\n ): Promise<Response> {\n return new Promise((resolve, reject) => {\n let shellRendered = false;\n const userAgent = request.headers.get('user-agent');\n\n // Determine if we should use onAllReady or onShellReady\n const isBot = typeof userAgent === 'string' && botRegex.test(userAgent);\n const isSpaMode = !!(routerContext as { isSpaMode?: boolean }).isSpaMode;\n\n const readyOption = isBot || isSpaMode ? 'onAllReady' : 'onShellReady';\n\n const { pipe, abort } = renderToPipeableStream(<ServerRouter context={routerContext} url={request.url} />, {\n [readyOption]() {\n shellRendered = true;\n const body = new PassThrough();\n\n const stream = createReadableStreamFromReadable(body);\n\n responseHeaders.set('Content-Type', 'text/html');\n\n resolve(\n new Response(stream, {\n headers: responseHeaders,\n status: responseStatusCode,\n }),\n );\n\n // this injects trace data to the HTML head\n pipe(getMetaTagTransformer(body));\n },\n onShellError(error: unknown) {\n reject(error);\n },\n onError(error: unknown) {\n // eslint-disable-next-line no-param-reassign\n responseStatusCode = 500;\n // Log streaming rendering errors from inside the shell. Don't log\n // errors encountered during initial shell rendering since they'll\n // reject and get logged in handleDocumentRequest.\n if (shellRendered) {\n // eslint-disable-next-line no-console\n console.error(error);\n }\n },\n });\n\n // Abort the rendering stream after the `streamTimeout`\n setTimeout(abort, streamTimeout);\n });\n };\n\n // Wrap the handle request function for request parametrization\n return wrapSentryHandleRequest(handleRequest as HandleRequestWithoutMiddleware) as HandleRequestWithoutMiddleware &\n HandleRequestWithMiddleware;\n}\n"],"names":["React","PassThrough","stream","getMetaTagTransformer","wrapSentryHandleRequest"],"mappings":";;;;;;;AAuEA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,yBAAyB;AACzC,EAAE,OAAO;AACT,EAAgE;AAChE,EAAE,MAAM;AACR,IAAI,aAAA,GAAgB,KAAK;AACzB,IAAI,sBAAsB;AAC1B,IAAI,YAAY;AAChB,IAAI,gCAAgC;AACpC,IAAI,QAAA,GAAW,oFAAoF;AACnG,GAAE,GAAI,OAAO;;AAEb,EAAE,MAAM,aAAA,GAAgB,SAAS,aAAa;AAC9C,IAAI,OAAO;AACX,IAAI,kBAAkB;AACtB,IAAI,eAAe;AACnB,IAAI,aAAa;AACjB,IAAI,YAAY;AAChB,IAAuB;AACvB,IAAI,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK;AAC5C,MAAM,IAAI,aAAA,GAAgB,KAAK;AAC/B,MAAM,MAAM,SAAA,GAAY,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;;AAEzD;AACA,MAAM,MAAM,KAAA,GAAQ,OAAO,SAAA,KAAc,QAAA,IAAY,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC;AAC7E,MAAM,MAAM,YAAY,CAAC,CAAC,CAAC,aAAA,GAA0C,SAAS;;AAE9E,MAAM,MAAM,cAAc,KAAA,IAAS,SAAA,GAAY,YAAA,GAAe,cAAc;;AAE5E,MAAM,MAAM,EAAE,IAAI,EAAE,OAAM,GAAI,sBAAsB,CAACA,aAAA,CAAA,aAAA,CAAC,YAAA,EAAA,EAAa,OAAO,EAAC,aAAc,EAAE,GAAG,EAAC,OAAQ,CAAC,GAAG,EAAA,EAAI,EAAE;AACjH,QAAQ,CAAC,WAAW,CAAC,GAAG;AACxB,UAAU,aAAA,GAAgB,IAAI;AAC9B,UAAU,MAAM,IAAA,GAAO,IAAIC,kBAAW,EAAE;;AAExC,UAAU,MAAMC,QAAA,GAAS,gCAAgC,CAAC,IAAI,CAAC;;AAE/D,UAAU,eAAe,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,CAAC;;AAE1D,UAAU,OAAO;AACjB,YAAY,IAAI,QAAQ,CAACA,QAAM,EAAE;AACjC,cAAc,OAAO,EAAE,eAAe;AACtC,cAAc,MAAM,EAAE,kBAAkB;AACxC,aAAa,CAAC;AACd,WAAW;;AAEX;AACA,UAAU,IAAI,CAACC,2CAAqB,CAAC,IAAI,CAAC,CAAC;AAC3C,QAAQ,CAAC;AACT,QAAQ,YAAY,CAAC,KAAK,EAAW;AACrC,UAAU,MAAM,CAAC,KAAK,CAAC;AACvB,QAAQ,CAAC;AACT,QAAQ,OAAO,CAAC,KAAK,EAAW;AAChC;AACA,UAAU,kBAAA,GAAqB,GAAG;AAClC;AACA;AACA;AACA,UAAU,IAAI,aAAa,EAAE;AAC7B;AACA,YAAY,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;AAChC,UAAU;AACV,QAAQ,CAAC;AACT,OAAO,CAAC;;AAER;AACA,MAAM,UAAU,CAAC,KAAK,EAAE,aAAa,CAAC;AACtC,IAAI,CAAC,CAAC;AACN,EAAE,CAAC;;AAEH;AACA,EAAE,OAAOC,+CAAuB,CAAC,aAAA;AAC7B;AACJ;;;;"}
1
+ {"version":3,"file":"createSentryHandleRequest.js","sources":["../../../src/server/createSentryHandleRequest.tsx"],"sourcesContent":["import type { createReadableStreamFromReadable } from '@react-router/node';\nimport type { ReactNode } from 'react';\nimport React from 'react';\nimport type { AppLoadContext, EntryContext, RouterContextProvider, ServerRouter } from 'react-router';\nimport { PassThrough } from 'stream';\nimport { getMetaTagTransformer } from './getMetaTagTransformer';\nimport { wrapSentryHandleRequest } from './wrapSentryHandleRequest';\n\ntype RenderToPipeableStreamOptions = {\n [key: string]: unknown;\n onShellReady?: () => void;\n onAllReady?: () => void;\n onShellError?: (error: unknown) => void;\n onError?: (error: unknown) => void;\n};\n\ntype RenderToPipeableStreamResult = {\n pipe: (destination: NodeJS.WritableStream) => void;\n abort: () => void;\n};\n\ntype RenderToPipeableStreamFunction = (\n node: ReactNode,\n options: RenderToPipeableStreamOptions,\n) => RenderToPipeableStreamResult;\n\nexport interface SentryHandleRequestOptions {\n /**\n * Timeout in milliseconds after which the rendering stream will be aborted\n * @default 10000\n */\n streamTimeout?: number;\n\n /**\n * React's renderToPipeableStream function from 'react-dom/server'\n */\n renderToPipeableStream: RenderToPipeableStreamFunction;\n\n /**\n * The <ServerRouter /> component from '@react-router/server'\n */\n ServerRouter: typeof ServerRouter;\n\n /**\n * createReadableStreamFromReadable from '@react-router/node'\n */\n createReadableStreamFromReadable: typeof createReadableStreamFromReadable;\n\n /**\n * Regular expression to identify bot user agents\n * @default /bot|crawler|spider|googlebot|chrome-lighthouse|baidu|bing|google|yahoo|lighthouse/i\n */\n botRegex?: RegExp;\n}\n\ntype HandleRequestWithoutMiddleware = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n) => Promise<unknown>;\n\ntype HandleRequestWithMiddleware = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: RouterContextProvider,\n) => Promise<unknown>;\n\n/**\n * A complete Sentry-instrumented handleRequest implementation that handles both\n * route parametrization and trace meta tag injection.\n *\n * @param options Configuration options\n * @returns A Sentry-instrumented handleRequest function\n */\nexport function createSentryHandleRequest(\n options: SentryHandleRequestOptions,\n): HandleRequestWithoutMiddleware & HandleRequestWithMiddleware {\n const {\n streamTimeout = 10000,\n renderToPipeableStream,\n ServerRouter,\n createReadableStreamFromReadable,\n botRegex = /bot|crawler|spider|googlebot|chrome-lighthouse|baidu|bing|google|yahoo|lighthouse/i,\n } = options;\n\n const handleRequest = function handleRequest(\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n _loadContext: AppLoadContext | RouterContextProvider,\n ): Promise<Response> {\n return new Promise((resolve, reject) => {\n let shellRendered = false;\n const userAgent = request.headers.get('user-agent');\n\n // Determine if we should use onAllReady or onShellReady\n const isBot = typeof userAgent === 'string' && botRegex.test(userAgent);\n const isSpaMode = !!(routerContext as { isSpaMode?: boolean }).isSpaMode;\n\n const readyOption = isBot || isSpaMode ? 'onAllReady' : 'onShellReady';\n\n const { pipe, abort } = renderToPipeableStream(<ServerRouter context={routerContext} url={request.url} />, {\n [readyOption]() {\n shellRendered = true;\n const body = new PassThrough();\n\n const stream = createReadableStreamFromReadable(body);\n\n responseHeaders.set('Content-Type', 'text/html');\n\n resolve(\n new Response(stream, {\n headers: responseHeaders,\n status: responseStatusCode,\n }),\n );\n\n // this injects trace data to the HTML head\n pipe(getMetaTagTransformer(body));\n },\n onShellError(error: unknown) {\n reject(error);\n },\n onError(error: unknown) {\n // eslint-disable-next-line no-param-reassign\n responseStatusCode = 500;\n // Log streaming rendering errors from inside the shell. Don't log\n // errors encountered during initial shell rendering since they'll\n // reject and get logged in handleDocumentRequest.\n if (shellRendered) {\n // eslint-disable-next-line no-console\n console.error(error);\n }\n },\n });\n\n // Abort the rendering stream after the `streamTimeout`\n setTimeout(abort, streamTimeout);\n });\n };\n\n // Wrap the handle request function for request parametrization\n return wrapSentryHandleRequest(handleRequest as HandleRequestWithoutMiddleware) as HandleRequestWithoutMiddleware &\n HandleRequestWithMiddleware;\n}\n"],"names":["handleRequest","React","PassThrough","stream","getMetaTagTransformer","wrapSentryHandleRequest"],"mappings":";;;;;;;AA8EO,SAAS,0BACd,OAAA,EAC8D;AAC9D,EAAA,MAAM;AAAA,IACJ,aAAA,GAAgB,GAAA;AAAA,IAChB,sBAAA;AAAA,IACA,YAAA;AAAA,IACA,gCAAA;AAAA,IACA,QAAA,GAAW;AAAA,GACb,GAAI,OAAA;AAEJ,EAAA,MAAM,gBAAgB,SAASA,cAAAA,CAC7B,SACA,kBAAA,EACA,eAAA,EACA,eACA,YAAA,EACmB;AACnB,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,MAAA,IAAI,aAAA,GAAgB,KAAA;AACpB,MAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,YAAY,CAAA;AAGlD,MAAA,MAAM,QAAQ,OAAO,SAAA,KAAc,QAAA,IAAY,QAAA,CAAS,KAAK,SAAS,CAAA;AACtE,MAAA,MAAM,SAAA,GAAY,CAAC,CAAE,aAAA,CAA0C,SAAA;AAE/D,MAAA,MAAM,WAAA,GAAc,KAAA,IAAS,SAAA,GAAY,YAAA,GAAe,cAAA;AAExD,MAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAM,GAAI,sBAAA,iBAAuBC,aAAA,CAAA,aAAA,CAAC,YAAA,EAAA,EAAa,OAAA,EAAS,aAAA,EAAe,GAAA,EAAK,OAAA,CAAQ,GAAA,EAAK,CAAA,EAAI;AAAA,QACzG,CAAC,WAAW,CAAA,GAAI;AACd,UAAA,aAAA,GAAgB,IAAA;AAChB,UAAA,MAAM,IAAA,GAAO,IAAIC,kBAAA,EAAY;AAE7B,UAAA,MAAMC,QAAA,GAAS,iCAAiC,IAAI,CAAA;AAEpD,UAAA,eAAA,CAAgB,GAAA,CAAI,gBAAgB,WAAW,CAAA;AAE/C,UAAA,OAAA;AAAA,YACE,IAAI,SAASA,QAAA,EAAQ;AAAA,cACnB,OAAA,EAAS,eAAA;AAAA,cACT,MAAA,EAAQ;AAAA,aACT;AAAA,WACH;AAGA,UAAA,IAAA,CAAKC,2CAAA,CAAsB,IAAI,CAAC,CAAA;AAAA,QAClC,CAAA;AAAA,QACA,aAAa,KAAA,EAAgB;AAC3B,UAAA,MAAA,CAAO,KAAK,CAAA;AAAA,QACd,CAAA;AAAA,QACA,QAAQ,KAAA,EAAgB;AAEtB,UAAA,kBAAA,GAAqB,GAAA;AAIrB,UAAA,IAAI,aAAA,EAAe;AAEjB,YAAA,OAAA,CAAQ,MAAM,KAAK,CAAA;AAAA,UACrB;AAAA,QACF;AAAA,OACD,CAAA;AAGD,MAAA,UAAA,CAAW,OAAO,aAAa,CAAA;AAAA,IACjC,CAAC,CAAA;AAAA,EACH,CAAA;AAGA,EAAA,OAAOC,gDAAwB,aAA+C,CAAA;AAEhF;;;;"}
@@ -9,51 +9,35 @@ const utils = require('../common/utils.js');
9
9
  const serverBuild = require('./serverBuild.js');
10
10
  const serverGlobals = require('./serverGlobals.js');
11
11
 
12
- const MIDDLEWARE_COUNTER_KEY = api.createContextKey('sentry_react_router_middleware_counter');
13
-
14
- /**
15
- * Options for creating Sentry server instrumentation.
16
- */
17
-
18
- /**
19
- * Creates a Sentry server instrumentation for React Router's instrumentation API.
20
- * @experimental
21
- */
22
- function createSentryServerInstrumentation(
23
- options = {},
24
- ) {
12
+ const MIDDLEWARE_COUNTER_KEY = api.createContextKey("sentry_react_router_middleware_counter");
13
+ function createSentryServerInstrumentation(options = {}) {
25
14
  const { captureErrors = true } = options;
26
-
27
15
  serverGlobals.markInstrumentationApiUsed();
28
- debugBuild.DEBUG_BUILD && core.debug.log('React Router server instrumentation API enabled.');
29
-
16
+ debugBuild.DEBUG_BUILD && core.debug.log("React Router server instrumentation API enabled.");
30
17
  return {
31
18
  handler(handler) {
32
19
  handler.instrument({
33
20
  async request(handleRequest, info) {
34
21
  const pathname = utils.getPathFromRequest(info.request);
35
22
  const activeSpan = core.getActiveSpan();
36
- const existingRootSpan = activeSpan ? core.getRootSpan(activeSpan) : undefined;
37
-
38
- const counterStore = { counters: {} };
23
+ const existingRootSpan = activeSpan ? core.getRootSpan(activeSpan) : void 0;
24
+ const counterStore = { counters: {} };
39
25
  const ctx = api.context.active().setValue(MIDDLEWARE_COUNTER_KEY, counterStore);
40
-
41
26
  await api.context.with(ctx, async () => {
42
27
  if (existingRootSpan) {
43
28
  core.updateSpanName(existingRootSpan, `${info.request.method} ${pathname}`);
44
29
  existingRootSpan.setAttributes({
45
- [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.server',
46
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.instrumentation_api',
47
- [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
30
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: "http.server",
31
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.http.react_router.instrumentation_api",
32
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "url"
48
33
  });
49
-
50
34
  try {
51
35
  const result = await handleRequest();
52
- if (result.status === 'error' && result.error instanceof Error) {
53
- existingRootSpan.setStatus({ code: core.SPAN_STATUS_ERROR, message: 'internal_error' });
54
- utils.captureInstrumentationError(result, captureErrors, 'react_router.request_handler', {
55
- 'http.method': info.request.method,
56
- 'http.url': pathname,
36
+ if (result.status === "error" && result.error instanceof Error) {
37
+ existingRootSpan.setStatus({ code: core.SPAN_STATUS_ERROR, message: "internal_error" });
38
+ utils.captureInstrumentationError(result, captureErrors, "react_router.request_handler", {
39
+ "http.method": info.request.method,
40
+ "http.url": pathname
57
41
  });
58
42
  }
59
43
  } finally {
@@ -65,188 +49,166 @@ function createSentryServerInstrumentation(
65
49
  name: `${info.request.method} ${pathname}`,
66
50
  forceTransaction: true,
67
51
  attributes: {
68
- [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.server',
69
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.instrumentation_api',
70
- [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
71
- 'http.request.method': info.request.method,
72
- 'url.path': pathname,
73
- 'url.full': info.request.url,
74
- },
52
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: "http.server",
53
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.http.react_router.instrumentation_api",
54
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "url",
55
+ "http.request.method": info.request.method,
56
+ "url.path": pathname,
57
+ "url.full": info.request.url
58
+ }
75
59
  },
76
- async span => {
60
+ async (span) => {
77
61
  try {
78
62
  const result = await handleRequest();
79
- if (result.status === 'error' && result.error instanceof Error) {
80
- span.setStatus({ code: core.SPAN_STATUS_ERROR, message: 'internal_error' });
81
- utils.captureInstrumentationError(result, captureErrors, 'react_router.request_handler', {
82
- 'http.method': info.request.method,
83
- 'http.url': pathname,
63
+ if (result.status === "error" && result.error instanceof Error) {
64
+ span.setStatus({ code: core.SPAN_STATUS_ERROR, message: "internal_error" });
65
+ utils.captureInstrumentationError(result, captureErrors, "react_router.request_handler", {
66
+ "http.method": info.request.method,
67
+ "http.url": pathname
84
68
  });
85
69
  }
86
70
  } finally {
87
71
  await core.flushIfServerless();
88
72
  }
89
- },
73
+ }
90
74
  );
91
75
  }
92
76
  });
93
- },
77
+ }
94
78
  });
95
79
  },
96
-
97
80
  route(route) {
98
81
  const routeId = route.id;
99
-
100
82
  route.instrument({
101
83
  async loader(callLoader, info) {
102
84
  const urlPath = utils.getPathFromRequest(info.request);
103
85
  const pattern = utils.getPattern(info);
104
86
  const routePattern = utils.normalizeRoutePath(pattern) || urlPath;
105
87
  updateRootSpanWithRoute(info.request.method, pattern, urlPath);
106
-
107
88
  await core.startSpan(
108
89
  {
109
90
  name: routePattern,
110
91
  attributes: {
111
- [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.loader',
112
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',
113
- },
92
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: "function.react_router.loader",
93
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.function.react_router.instrumentation_api"
94
+ }
114
95
  },
115
- async span => {
96
+ async (span) => {
116
97
  const result = await callLoader();
117
- if (result.status === 'error' && result.error instanceof Error) {
118
- span.setStatus({ code: core.SPAN_STATUS_ERROR, message: 'internal_error' });
119
- utils.captureInstrumentationError(result, captureErrors, 'react_router.loader', {
120
- 'http.method': info.request.method,
121
- 'http.url': urlPath,
98
+ if (result.status === "error" && result.error instanceof Error) {
99
+ span.setStatus({ code: core.SPAN_STATUS_ERROR, message: "internal_error" });
100
+ utils.captureInstrumentationError(result, captureErrors, "react_router.loader", {
101
+ "http.method": info.request.method,
102
+ "http.url": urlPath
122
103
  });
123
104
  }
124
- },
105
+ }
125
106
  );
126
107
  },
127
-
128
108
  async action(callAction, info) {
129
109
  const urlPath = utils.getPathFromRequest(info.request);
130
110
  const pattern = utils.getPattern(info);
131
111
  const routePattern = utils.normalizeRoutePath(pattern) || urlPath;
132
112
  updateRootSpanWithRoute(info.request.method, pattern, urlPath);
133
-
134
113
  await core.startSpan(
135
114
  {
136
115
  name: routePattern,
137
116
  attributes: {
138
- [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.action',
139
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',
140
- },
117
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: "function.react_router.action",
118
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.function.react_router.instrumentation_api"
119
+ }
141
120
  },
142
- async span => {
121
+ async (span) => {
143
122
  const result = await callAction();
144
- if (result.status === 'error' && result.error instanceof Error) {
145
- span.setStatus({ code: core.SPAN_STATUS_ERROR, message: 'internal_error' });
146
- utils.captureInstrumentationError(result, captureErrors, 'react_router.action', {
147
- 'http.method': info.request.method,
148
- 'http.url': urlPath,
123
+ if (result.status === "error" && result.error instanceof Error) {
124
+ span.setStatus({ code: core.SPAN_STATUS_ERROR, message: "internal_error" });
125
+ utils.captureInstrumentationError(result, captureErrors, "react_router.action", {
126
+ "http.method": info.request.method,
127
+ "http.url": urlPath
149
128
  });
150
129
  }
151
- },
130
+ }
152
131
  );
153
132
  },
154
-
155
133
  async middleware(callMiddleware, info) {
156
134
  const urlPath = utils.getPathFromRequest(info.request);
157
135
  const pattern = utils.getPattern(info);
158
136
  const routePattern = utils.normalizeRoutePath(pattern) || urlPath;
159
-
160
137
  updateRootSpanWithRoute(info.request.method, pattern, urlPath);
161
-
162
- const counterStore = api.context.active().getValue(MIDDLEWARE_COUNTER_KEY)
163
-
164
- ;
138
+ const counterStore = api.context.active().getValue(MIDDLEWARE_COUNTER_KEY);
165
139
  let middlewareIndex = 0;
166
140
  if (counterStore) {
167
141
  middlewareIndex = counterStore.counters[routeId] ?? 0;
168
142
  counterStore.counters[routeId] = middlewareIndex + 1;
169
143
  }
170
-
171
144
  const middlewareName = serverBuild.getMiddlewareName(routeId, middlewareIndex);
172
-
173
145
  await core.startSpan(
174
146
  {
175
147
  name: `middleware ${middlewareName || routeId}`,
176
148
  attributes: {
177
- [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.middleware',
178
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',
179
- 'react_router.route.id': routeId,
149
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: "function.react_router.middleware",
150
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.function.react_router.instrumentation_api",
151
+ "react_router.route.id": routeId,
180
152
  [semanticConventions.ATTR_HTTP_ROUTE]: routePattern,
181
- ...(middlewareName && { 'react_router.middleware.name': middlewareName }),
182
- 'react_router.middleware.index': middlewareIndex,
183
- },
153
+ ...middlewareName && { "react_router.middleware.name": middlewareName },
154
+ "react_router.middleware.index": middlewareIndex
155
+ }
184
156
  },
185
- async span => {
157
+ async (span) => {
186
158
  const result = await callMiddleware();
187
- if (result.status === 'error' && result.error instanceof Error) {
188
- span.setStatus({ code: core.SPAN_STATUS_ERROR, message: 'internal_error' });
189
- utils.captureInstrumentationError(result, captureErrors, 'react_router.middleware', {
190
- 'http.method': info.request.method,
191
- 'http.url': urlPath,
159
+ if (result.status === "error" && result.error instanceof Error) {
160
+ span.setStatus({ code: core.SPAN_STATUS_ERROR, message: "internal_error" });
161
+ utils.captureInstrumentationError(result, captureErrors, "react_router.middleware", {
162
+ "http.method": info.request.method,
163
+ "http.url": urlPath
192
164
  });
193
165
  }
194
- },
166
+ }
195
167
  );
196
168
  },
197
-
198
169
  async lazy(callLazy) {
199
170
  await core.startSpan(
200
171
  {
201
- name: 'Lazy Route Load',
172
+ name: "Lazy Route Load",
202
173
  attributes: {
203
- [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.lazy',
204
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',
205
- },
174
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: "function.react_router.lazy",
175
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.function.react_router.instrumentation_api"
176
+ }
206
177
  },
207
- async span => {
178
+ async (span) => {
208
179
  const result = await callLazy();
209
- if (result.status === 'error' && result.error instanceof Error) {
210
- span.setStatus({ code: core.SPAN_STATUS_ERROR, message: 'internal_error' });
211
- utils.captureInstrumentationError(result, captureErrors, 'react_router.lazy', {});
180
+ if (result.status === "error" && result.error instanceof Error) {
181
+ span.setStatus({ code: core.SPAN_STATUS_ERROR, message: "internal_error" });
182
+ utils.captureInstrumentationError(result, captureErrors, "react_router.lazy", {});
212
183
  }
213
- },
184
+ }
214
185
  );
215
- },
186
+ }
216
187
  });
217
- },
188
+ }
218
189
  };
219
190
  }
220
-
221
191
  function updateRootSpanWithRoute(method, pattern, urlPath) {
222
192
  const activeSpan = core.getActiveSpan();
223
193
  if (!activeSpan) return;
224
194
  const rootSpan = core.getRootSpan(activeSpan);
225
195
  if (!rootSpan) return;
226
-
227
- // Skip update if URL path is invalid (failed to parse)
228
- if (!urlPath || urlPath === '<unknown>') {
229
- debugBuild.DEBUG_BUILD && core.debug.warn('Cannot update span with invalid URL path:', urlPath);
196
+ if (!urlPath || urlPath === "<unknown>") {
197
+ debugBuild.DEBUG_BUILD && core.debug.warn("Cannot update span with invalid URL path:", urlPath);
230
198
  return;
231
199
  }
232
-
233
200
  const hasPattern = !!pattern;
234
201
  const routeName = hasPattern ? utils.normalizeRoutePath(pattern) || urlPath : urlPath;
235
-
236
202
  const rpcMetadata = core$1.getRPCMetadata(api.context.active());
237
203
  if (rpcMetadata?.type === core$1.RPCType.HTTP) {
238
204
  rpcMetadata.route = routeName;
239
205
  }
240
-
241
206
  const transactionName = `${method} ${routeName}`;
242
207
  core.updateSpanName(rootSpan, transactionName);
243
208
  rootSpan.setAttributes({
244
209
  [semanticConventions.ATTR_HTTP_ROUTE]: routeName,
245
- [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: hasPattern ? 'route' : 'url',
210
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: hasPattern ? "route" : "url"
246
211
  });
247
-
248
- // Also update the scope's transaction name so errors captured during this request
249
- // have the correct transaction name (not the initial placeholder like "GET *")
250
212
  core.getCurrentScope().setTransactionName(transactionName);
251
213
  }
252
214