@depup/sentry__react 10.75.2-depup.0 → 11.1.0-depup.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.
- package/README.md +3 -9
- package/build/cjs/error.js +4 -10
- package/build/cjs/error.js.map +1 -1
- package/build/cjs/hoist-non-react-statics.js +1 -7
- package/build/cjs/hoist-non-react-statics.js.map +1 -1
- package/build/cjs/profiler.js +45 -19
- package/build/cjs/profiler.js.map +1 -1
- package/build/cjs/react-router.js +21 -0
- package/build/cjs/react-router.js.map +1 -0
- package/build/cjs/reactrouter-compat-utils/instrumentation.js +200 -192
- package/build/cjs/reactrouter-compat-utils/instrumentation.js.map +1 -1
- package/build/cjs/reactrouter-compat-utils/route-manifest.js +4 -4
- package/build/cjs/reactrouter-compat-utils/route-manifest.js.map +1 -1
- package/build/cjs/reactrouter-compat-utils/utils.js +34 -37
- package/build/cjs/reactrouter-compat-utils/utils.js.map +1 -1
- package/build/cjs/reactrouter.compat.js +0 -3
- package/build/cjs/reactrouter.compat.js.map +1 -1
- package/build/cjs/reactrouter.js +14 -8
- package/build/cjs/reactrouter.js.map +1 -1
- package/build/cjs/reactrouterv3.js +12 -9
- package/build/cjs/reactrouterv3.js.map +1 -1
- package/build/cjs/reactrouterv6.js +0 -3
- package/build/cjs/reactrouterv6.js.map +1 -1
- package/build/cjs/reactrouterv7.js +0 -3
- package/build/cjs/reactrouterv7.js.map +1 -1
- package/build/cjs/redux.js +6 -6
- package/build/cjs/redux.js.map +1 -1
- package/build/cjs/sdk.js +7 -7
- package/build/cjs/sdk.js.map +1 -1
- package/build/cjs/tanstackrouter.js +23 -13
- package/build/cjs/tanstackrouter.js.map +1 -1
- package/build/esm/error.js +3 -8
- package/build/esm/error.js.map +1 -1
- package/build/esm/hoist-non-react-statics.js +1 -7
- package/build/esm/hoist-non-react-statics.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/build/esm/profiler.js +47 -21
- package/build/esm/profiler.js.map +1 -1
- package/build/esm/react-router.js +16 -0
- package/build/esm/react-router.js.map +1 -0
- package/build/esm/reactrouter-compat-utils/instrumentation.js +203 -195
- package/build/esm/reactrouter-compat-utils/instrumentation.js.map +1 -1
- package/build/esm/reactrouter-compat-utils/route-manifest.js +1 -1
- package/build/esm/reactrouter-compat-utils/route-manifest.js.map +1 -1
- package/build/esm/reactrouter-compat-utils/utils.js +32 -34
- package/build/esm/reactrouter-compat-utils/utils.js.map +1 -1
- package/build/esm/reactrouter.compat.js +0 -3
- package/build/esm/reactrouter.compat.js.map +1 -1
- package/build/esm/reactrouter.js +16 -10
- package/build/esm/reactrouter.js.map +1 -1
- package/build/esm/reactrouterv3.js +11 -8
- package/build/esm/reactrouterv3.js.map +1 -1
- package/build/esm/reactrouterv6.js +0 -3
- package/build/esm/reactrouterv6.js.map +1 -1
- package/build/esm/reactrouterv7.js +0 -3
- package/build/esm/reactrouterv7.js.map +1 -1
- package/build/esm/redux.js +1 -1
- package/build/esm/redux.js.map +1 -1
- package/build/esm/sdk.js +1 -1
- package/build/esm/sdk.js.map +1 -1
- package/build/esm/tanstackrouter.js +23 -13
- package/build/esm/tanstackrouter.js.map +1 -1
- package/build/types/error.d.ts +0 -4
- package/build/types/error.d.ts.map +1 -1
- package/build/types/errorboundary.d.ts.map +1 -1
- package/build/types/hoist-non-react-statics.d.ts.map +1 -1
- package/build/types/profiler.d.ts +0 -1
- package/build/types/profiler.d.ts.map +1 -1
- package/build/types/react-router.d.ts +26 -0
- package/build/types/react-router.d.ts.map +1 -0
- package/build/types/reactrouter-compat-utils/index.d.ts +1 -1
- package/build/types/reactrouter-compat-utils/index.d.ts.map +1 -1
- package/build/types/reactrouter-compat-utils/instrumentation.d.ts +9 -5
- package/build/types/reactrouter-compat-utils/instrumentation.d.ts.map +1 -1
- package/build/types/reactrouter-compat-utils/utils.d.ts +6 -11
- package/build/types/reactrouter-compat-utils/utils.d.ts.map +1 -1
- package/build/types/reactrouter.d.ts +16 -0
- package/build/types/reactrouter.d.ts.map +1 -1
- package/build/types/reactrouterv3.d.ts +1 -1
- package/build/types/reactrouterv3.d.ts.map +1 -1
- package/build/types/redux.d.ts +1 -1
- package/build/types/redux.d.ts.map +1 -1
- package/build/types/sdk.d.ts +1 -1
- package/build/types/sdk.d.ts.map +1 -1
- package/build/types/tanstackrouter.d.ts +1 -1
- package/build/types/tanstackrouter.d.ts.map +1 -1
- package/build/types/types.d.ts +16 -0
- package/build/types/types.d.ts.map +1 -1
- package/changes.json +3 -8
- package/package.json +39 -26
- package/build/cjs/constants.js +0 -10
- package/build/cjs/constants.js.map +0 -1
- package/build/esm/constants.js +0 -6
- package/build/esm/constants.js.map +0 -1
- package/build/types/constants.d.ts +0 -4
- package/build/types/constants.d.ts.map +0 -1
- package/build/types-ts3.8/constants.d.ts +0 -4
- package/build/types-ts3.8/debug-build.d.ts +0 -7
- package/build/types-ts3.8/error.d.ts +0 -41
- package/build/types-ts3.8/errorboundary.d.ts +0 -87
- package/build/types-ts3.8/hoist-non-react-statics.d.ts +0 -21
- package/build/types-ts3.8/index.d.ts +0 -14
- package/build/types-ts3.8/isSyntheticEvent.d.ts +0 -10
- package/build/types-ts3.8/profiler.d.ts +0 -56
- package/build/types-ts3.8/reactrouter-compat-utils/index.d.ts +0 -5
- package/build/types-ts3.8/reactrouter-compat-utils/instrumentation.d.ts +0 -117
- package/build/types-ts3.8/reactrouter-compat-utils/lazy-routes.d.ts +0 -18
- package/build/types-ts3.8/reactrouter-compat-utils/route-manifest.d.ts +0 -13
- package/build/types-ts3.8/reactrouter-compat-utils/utils.d.ts +0 -77
- package/build/types-ts3.8/reactrouter.compat.d.ts +0 -42
- package/build/types-ts3.8/reactrouter.d.ts +0 -41
- package/build/types-ts3.8/reactrouterv3.d.ts +0 -29
- package/build/types-ts3.8/reactrouterv6.d.ts +0 -42
- package/build/types-ts3.8/reactrouterv7.d.ts +0 -42
- package/build/types-ts3.8/redux.d.ts +0 -38
- package/build/types-ts3.8/sdk.d.ts +0 -7
- package/build/types-ts3.8/tanstackrouter.d.ts +0 -13
- package/build/types-ts3.8/types.d.ts +0 -163
- package/build/types-ts3.8/vendor/tanstackrouter-types.d.ts +0 -38
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
import { WINDOW, browserTracingIntegration, startBrowserTracingPageLoadSpan, startBrowserTracingNavigationSpan } from '@sentry/browser';
|
|
2
|
-
import {
|
|
2
|
+
import { extendIntegration, PAGELOAD_SPAN_NAME_FALLBACK, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, hasSpanStreamingEnabled, debug, getClient, addNonEnumerableProperty, spanToJSON, getCurrentScope, NAVIGATION_SPAN_NAME_FALLBACK } from '@sentry/core';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { DEBUG_BUILD } from '../debug-build.js';
|
|
5
5
|
import { hoistNonReactStatics } from '../hoist-non-react-statics.js';
|
|
6
6
|
import { checkRouteForAsyncHandler } from './lazy-routes.js';
|
|
7
|
-
import { getActiveRootSpan, setNavigationContext, clearNavigationContext, resolveRouteNameAndSource, transactionNameHasWildcard
|
|
8
|
-
import { URL_TEMPLATE } from '@sentry/conventions/attributes';
|
|
7
|
+
import { getActiveRootSpan, setNavigationContext, clearNavigationContext, resolveRouteNameAndSource, transactionNameHasWildcard } from './utils.js';
|
|
8
|
+
import { SENTRY_OP, SENTRY_SEGMENT_NAME_SOURCE, URL_TEMPLATE } from '@sentry/conventions/attributes';
|
|
9
|
+
import { PAGELOAD, NAVIGATION } from '@sentry/conventions/op';
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
let _matchRoutes;
|
|
15
|
-
let _enableAsyncRouteHandlers = false;
|
|
16
|
-
let _lazyRouteTimeout = 3e3;
|
|
17
|
-
let _lazyRouteManifest;
|
|
18
|
-
let _basename = "";
|
|
19
|
-
const CLIENTS_WITH_INSTRUMENT_NAVIGATION = /* @__PURE__ */ new WeakSet();
|
|
11
|
+
const reactRouterConfigByClient = /* @__PURE__ */ new WeakMap();
|
|
12
|
+
function getRouterConfig(client) {
|
|
13
|
+
return client ? reactRouterConfigByClient.get(client) : void 0;
|
|
14
|
+
}
|
|
20
15
|
const useIsomorphicLayoutEffect = WINDOW?.document ? React.useLayoutEffect : React.useEffect;
|
|
21
16
|
const activeNavigationSpans = /* @__PURE__ */ new WeakMap();
|
|
22
17
|
const allRoutes = /* @__PURE__ */ new Set();
|
|
@@ -100,11 +95,11 @@ function resolveDeferredLazyRoutePromise(span) {
|
|
|
100
95
|
}
|
|
101
96
|
}
|
|
102
97
|
}
|
|
103
|
-
function processResolvedRoutes(resolvedRoutes, parentRoute, currentLocation = null, capturedSpan) {
|
|
98
|
+
function processResolvedRoutes(resolvedRoutes, config, parentRoute, currentLocation = null, capturedSpan) {
|
|
104
99
|
resolvedRoutes.forEach((child) => {
|
|
105
100
|
allRoutes.add(child);
|
|
106
|
-
if (
|
|
107
|
-
checkRouteForAsyncHandler(child, processResolvedRoutes);
|
|
101
|
+
if (config.enableAsyncRouteHandlers) {
|
|
102
|
+
checkRouteForAsyncHandler(child, (r, p, l, s) => processResolvedRoutes(r, config, p, l, s));
|
|
108
103
|
}
|
|
109
104
|
});
|
|
110
105
|
if (parentRoute) {
|
|
@@ -112,12 +107,12 @@ function processResolvedRoutes(resolvedRoutes, parentRoute, currentLocation = nu
|
|
|
112
107
|
}
|
|
113
108
|
const targetSpan = capturedSpan ?? getActiveRootSpan();
|
|
114
109
|
if (targetSpan) {
|
|
115
|
-
const
|
|
116
|
-
if (
|
|
110
|
+
const { end_timestamp, attributes } = spanToJSON(targetSpan);
|
|
111
|
+
if (end_timestamp) {
|
|
117
112
|
DEBUG_BUILD && debug.warn("[React Router] Lazy handler resolved after span ended - skipping update");
|
|
118
113
|
return;
|
|
119
114
|
}
|
|
120
|
-
const spanOp =
|
|
115
|
+
const spanOp = attributes[SENTRY_OP];
|
|
121
116
|
let location = currentLocation;
|
|
122
117
|
if (!location && !capturedSpan) {
|
|
123
118
|
if (typeof WINDOW !== "undefined") {
|
|
@@ -133,62 +128,65 @@ function processResolvedRoutes(resolvedRoutes, parentRoute, currentLocation = nu
|
|
|
133
128
|
activeRootSpan: targetSpan,
|
|
134
129
|
location: { pathname: location.pathname },
|
|
135
130
|
routes: Array.from(allRoutes),
|
|
136
|
-
allRoutes: Array.from(allRoutes)
|
|
131
|
+
allRoutes: Array.from(allRoutes),
|
|
132
|
+
config
|
|
137
133
|
});
|
|
138
134
|
} else if (spanOp === "navigation") {
|
|
139
|
-
updateNavigationSpan(targetSpan, location, Array.from(allRoutes), false,
|
|
135
|
+
updateNavigationSpan(targetSpan, location, Array.from(allRoutes), false, config);
|
|
140
136
|
}
|
|
141
137
|
}
|
|
142
138
|
}
|
|
143
139
|
}
|
|
144
|
-
function updateNavigationSpan(activeRootSpan, location, allRoutes2, forceUpdate = false,
|
|
145
|
-
const
|
|
146
|
-
const
|
|
140
|
+
function updateNavigationSpan(activeRootSpan, location, allRoutes2, forceUpdate = false, config) {
|
|
141
|
+
const { name: currentName, end_timestamp, attributes } = spanToJSON(activeRootSpan);
|
|
142
|
+
const spanPathname = activeRootSpan?.__sentry_navigation_pathname__;
|
|
143
|
+
if (spanPathname !== void 0 && spanPathname !== location.pathname) {
|
|
144
|
+
DEBUG_BUILD && debug.log(
|
|
145
|
+
`[React Router] Not renaming the navigation span for "${spanPathname}" with the route of "${location.pathname}"`
|
|
146
|
+
);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
147
149
|
const hasBeenNamed = activeRootSpan?.__sentry_navigation_name_set__;
|
|
148
150
|
const currentNameHasWildcard = currentName && transactionNameHasWildcard(currentName);
|
|
149
151
|
const shouldUpdate = !hasBeenNamed || forceUpdate || currentNameHasWildcard;
|
|
150
|
-
if (shouldUpdate && !
|
|
151
|
-
const currentBranches = matchRoutes(allRoutes2, location);
|
|
152
|
+
if (shouldUpdate && !end_timestamp) {
|
|
153
|
+
const currentBranches = config.matchRoutes(allRoutes2, location);
|
|
152
154
|
const [name, source] = resolveRouteNameAndSource(
|
|
153
155
|
location,
|
|
154
156
|
allRoutes2,
|
|
155
157
|
allRoutes2,
|
|
156
158
|
currentBranches || [],
|
|
157
|
-
|
|
158
|
-
_lazyRouteManifest,
|
|
159
|
-
_enableAsyncRouteHandlers
|
|
159
|
+
config
|
|
160
160
|
);
|
|
161
|
-
const currentSource =
|
|
161
|
+
const currentSource = attributes[SENTRY_SEGMENT_NAME_SOURCE];
|
|
162
162
|
const isImprovement = name && (!currentName || // No current name - always set
|
|
163
163
|
!hasBeenNamed && (currentSource !== "route" || source === "route") || // Not finalized - allow unless downgrading route→url
|
|
164
164
|
currentSource !== "route" && source === "route" || // URL → route upgrade
|
|
165
165
|
currentSource === "route" && source === "route" && currentNameHasWildcard);
|
|
166
166
|
if (isImprovement) {
|
|
167
|
-
|
|
168
|
-
|
|
167
|
+
const client = getClient();
|
|
168
|
+
const isUnparameterizedStreamedNavigation = source !== "route" && !!client && hasSpanStreamingEnabled(client);
|
|
169
|
+
activeRootSpan.updateName(isUnparameterizedStreamedNavigation ? NAVIGATION_SPAN_NAME_FALLBACK : name);
|
|
170
|
+
activeRootSpan.setAttribute(SENTRY_SEGMENT_NAME_SOURCE, source);
|
|
169
171
|
if (source === "route") {
|
|
170
172
|
activeRootSpan.setAttribute(URL_TEMPLATE, name);
|
|
171
173
|
}
|
|
172
174
|
if (!transactionNameHasWildcard(name) && source === "route") {
|
|
173
|
-
addNonEnumerableProperty(
|
|
174
|
-
activeRootSpan,
|
|
175
|
-
"__sentry_navigation_name_set__",
|
|
176
|
-
true
|
|
177
|
-
);
|
|
175
|
+
addNonEnumerableProperty(activeRootSpan, "__sentry_navigation_name_set__", true);
|
|
178
176
|
}
|
|
179
177
|
}
|
|
180
178
|
}
|
|
181
179
|
}
|
|
182
|
-
function setupRouterSubscription(router, routes, version,
|
|
180
|
+
function setupRouterSubscription(router, routes, version, activeRootSpan, config) {
|
|
183
181
|
let isInitialPageloadComplete = false;
|
|
184
|
-
let hasSeenPageloadSpan = !!activeRootSpan && spanToJSON(activeRootSpan).
|
|
182
|
+
let hasSeenPageloadSpan = !!activeRootSpan && spanToJSON(activeRootSpan).attributes[SENTRY_OP] === "pageload";
|
|
185
183
|
let hasSeenPopAfterPageload = false;
|
|
186
184
|
let scheduledNavigationHandler = null;
|
|
187
185
|
let lastHandledPathname = null;
|
|
188
186
|
router.subscribe((state) => {
|
|
189
187
|
if (!isInitialPageloadComplete) {
|
|
190
188
|
const currentRootSpan = getActiveRootSpan();
|
|
191
|
-
const isCurrentlyInPageload = currentRootSpan && spanToJSON(currentRootSpan).
|
|
189
|
+
const isCurrentlyInPageload = currentRootSpan && spanToJSON(currentRootSpan).attributes[SENTRY_OP] === "pageload";
|
|
192
190
|
if (isCurrentlyInPageload) {
|
|
193
191
|
hasSeenPageloadSpan = true;
|
|
194
192
|
} else if (hasSeenPageloadSpan) {
|
|
@@ -213,8 +211,8 @@ function setupRouterSubscription(router, routes, version, basename, activeRootSp
|
|
|
213
211
|
routes,
|
|
214
212
|
navigationType: state.historyAction,
|
|
215
213
|
version,
|
|
216
|
-
|
|
217
|
-
|
|
214
|
+
allRoutes: Array.from(allRoutes),
|
|
215
|
+
config
|
|
218
216
|
});
|
|
219
217
|
};
|
|
220
218
|
if (state.navigation.state !== "idle") {
|
|
@@ -236,73 +234,66 @@ function setupRouterSubscription(router, routes, version, basename, activeRootSp
|
|
|
236
234
|
});
|
|
237
235
|
}
|
|
238
236
|
function createV6CompatibleWrapCreateBrowserRouter(createRouterFunction, version) {
|
|
239
|
-
if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes) {
|
|
240
|
-
DEBUG_BUILD && debug.warn(
|
|
241
|
-
`reactRouter${version ? `V${version}` : ""}Instrumentation was unable to wrap the \`createRouter\` function because of one or more missing parameters.`
|
|
242
|
-
);
|
|
243
|
-
return createRouterFunction;
|
|
244
|
-
}
|
|
245
237
|
return function(routes, opts) {
|
|
238
|
+
const base = getRouterConfig(getClient());
|
|
239
|
+
if (!base) {
|
|
240
|
+
DEBUG_BUILD && debug.warn(
|
|
241
|
+
`reactRouter${version ? `V${version}` : ""}Instrumentation was unable to wrap the \`createRouter\` function because the React Router browser tracing integration was not set up. Make sure \`Sentry.init()\` runs before the router is created.`
|
|
242
|
+
);
|
|
243
|
+
return createRouterFunction(routes, opts);
|
|
244
|
+
}
|
|
245
|
+
const config = { ...base, basename: opts?.basename || "" };
|
|
246
246
|
addRoutesToAllRoutes(routes);
|
|
247
|
-
if (
|
|
247
|
+
if (config.enableAsyncRouteHandlers) {
|
|
248
248
|
for (const route of routes) {
|
|
249
|
-
checkRouteForAsyncHandler(route, processResolvedRoutes);
|
|
249
|
+
checkRouteForAsyncHandler(route, (r, p, l, s) => processResolvedRoutes(r, config, p, l, s));
|
|
250
250
|
}
|
|
251
251
|
}
|
|
252
252
|
const activeRootSpan = getActiveRootSpan();
|
|
253
253
|
const hasPatchRoutesOnNavigation = opts && "patchRoutesOnNavigation" in opts && typeof opts.patchRoutesOnNavigation === "function";
|
|
254
254
|
if (hasPatchRoutesOnNavigation && activeRootSpan) {
|
|
255
|
-
addNonEnumerableProperty(
|
|
256
|
-
activeRootSpan,
|
|
257
|
-
"__sentry_may_have_lazy_routes__",
|
|
258
|
-
true
|
|
259
|
-
);
|
|
255
|
+
addNonEnumerableProperty(activeRootSpan, "__sentry_may_have_lazy_routes__", true);
|
|
260
256
|
createDeferredLazyRoutePromise(activeRootSpan);
|
|
261
257
|
}
|
|
262
|
-
const wrappedOpts = wrapPatchRoutesOnNavigation(opts, false, activeRootSpan);
|
|
258
|
+
const wrappedOpts = wrapPatchRoutesOnNavigation(opts, false, activeRootSpan, config);
|
|
263
259
|
const router = createRouterFunction(routes, wrappedOpts);
|
|
264
|
-
const basename = opts?.basename;
|
|
265
260
|
if (router.state.historyAction === "POP" && activeRootSpan) {
|
|
266
261
|
updatePageloadTransaction({
|
|
267
262
|
activeRootSpan,
|
|
268
263
|
location: router.state.location,
|
|
269
264
|
routes,
|
|
270
|
-
|
|
271
|
-
|
|
265
|
+
allRoutes: Array.from(allRoutes),
|
|
266
|
+
config
|
|
272
267
|
});
|
|
273
268
|
}
|
|
274
|
-
|
|
275
|
-
setupRouterSubscription(router, routes, version, basename, activeRootSpan);
|
|
269
|
+
setupRouterSubscription(router, routes, version, activeRootSpan, config);
|
|
276
270
|
return router;
|
|
277
271
|
};
|
|
278
272
|
}
|
|
279
273
|
function createV6CompatibleWrapCreateMemoryRouter(createRouterFunction, version) {
|
|
280
|
-
if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes) {
|
|
281
|
-
DEBUG_BUILD && debug.warn(
|
|
282
|
-
`reactRouter${version ? `V${version}` : ""}Instrumentation was unable to wrap the \`createMemoryRouter\` function because of one or more missing parameters.`
|
|
283
|
-
);
|
|
284
|
-
return createRouterFunction;
|
|
285
|
-
}
|
|
286
274
|
return function(routes, opts) {
|
|
275
|
+
const base = getRouterConfig(getClient());
|
|
276
|
+
if (!base) {
|
|
277
|
+
DEBUG_BUILD && debug.warn(
|
|
278
|
+
`reactRouter${version ? `V${version}` : ""}Instrumentation was unable to wrap the \`createMemoryRouter\` function because the React Router browser tracing integration was not set up. Make sure \`Sentry.init()\` runs before the router is created.`
|
|
279
|
+
);
|
|
280
|
+
return createRouterFunction(routes, opts);
|
|
281
|
+
}
|
|
282
|
+
const config = { ...base, basename: opts?.basename || "" };
|
|
287
283
|
addRoutesToAllRoutes(routes);
|
|
288
|
-
if (
|
|
284
|
+
if (config.enableAsyncRouteHandlers) {
|
|
289
285
|
for (const route of routes) {
|
|
290
|
-
checkRouteForAsyncHandler(route, processResolvedRoutes);
|
|
286
|
+
checkRouteForAsyncHandler(route, (r, p, l, s) => processResolvedRoutes(r, config, p, l, s));
|
|
291
287
|
}
|
|
292
288
|
}
|
|
293
289
|
const memoryActiveRootSpanEarly = getActiveRootSpan();
|
|
294
290
|
const hasPatchRoutesOnNavigation = opts && "patchRoutesOnNavigation" in opts && typeof opts.patchRoutesOnNavigation === "function";
|
|
295
291
|
if (hasPatchRoutesOnNavigation && memoryActiveRootSpanEarly) {
|
|
296
|
-
addNonEnumerableProperty(
|
|
297
|
-
memoryActiveRootSpanEarly,
|
|
298
|
-
"__sentry_may_have_lazy_routes__",
|
|
299
|
-
true
|
|
300
|
-
);
|
|
292
|
+
addNonEnumerableProperty(memoryActiveRootSpanEarly, "__sentry_may_have_lazy_routes__", true);
|
|
301
293
|
createDeferredLazyRoutePromise(memoryActiveRootSpanEarly);
|
|
302
294
|
}
|
|
303
|
-
const wrappedOpts = wrapPatchRoutesOnNavigation(opts, true, memoryActiveRootSpanEarly);
|
|
295
|
+
const wrappedOpts = wrapPatchRoutesOnNavigation(opts, true, memoryActiveRootSpanEarly, config);
|
|
304
296
|
const router = createRouterFunction(routes, wrappedOpts);
|
|
305
|
-
const basename = opts?.basename;
|
|
306
297
|
let initialEntry = void 0;
|
|
307
298
|
const initialEntries = opts?.initialEntries;
|
|
308
299
|
const initialIndex = opts?.initialIndex;
|
|
@@ -316,19 +307,17 @@ function createV6CompatibleWrapCreateMemoryRouter(createRouterFunction, version)
|
|
|
316
307
|
activeRootSpan: memoryActiveRootSpan,
|
|
317
308
|
location,
|
|
318
309
|
routes,
|
|
319
|
-
|
|
320
|
-
|
|
310
|
+
allRoutes: Array.from(allRoutes),
|
|
311
|
+
config
|
|
321
312
|
});
|
|
322
313
|
}
|
|
323
|
-
|
|
324
|
-
setupRouterSubscription(router, routes, version, basename, memoryActiveRootSpan);
|
|
314
|
+
setupRouterSubscription(router, routes, version, memoryActiveRootSpan, config);
|
|
325
315
|
return router;
|
|
326
316
|
};
|
|
327
317
|
}
|
|
328
318
|
function createReactRouterV6CompatibleTracingIntegration(options, version) {
|
|
329
319
|
const integration = browserTracingIntegration({ ...options, instrumentPageLoad: false, instrumentNavigation: false });
|
|
330
320
|
const {
|
|
331
|
-
useEffect,
|
|
332
321
|
useLocation,
|
|
333
322
|
useNavigationType,
|
|
334
323
|
createRoutesFromChildren,
|
|
@@ -340,15 +329,14 @@ function createReactRouterV6CompatibleTracingIntegration(options, version) {
|
|
|
340
329
|
lazyRouteTimeout,
|
|
341
330
|
lazyRouteManifest
|
|
342
331
|
} = options;
|
|
343
|
-
return {
|
|
344
|
-
...integration,
|
|
332
|
+
return extendIntegration(integration, {
|
|
345
333
|
setup(client) {
|
|
346
|
-
integration.setup(client);
|
|
347
334
|
const finalTimeout = options.finalTimeout ?? 3e4;
|
|
348
335
|
const defaultMaxWait = (options.idleTimeout ?? 1e3) * 3;
|
|
349
336
|
const configuredMaxWait = lazyRouteTimeout ?? defaultMaxWait;
|
|
337
|
+
let resolvedLazyRouteTimeout;
|
|
350
338
|
if (configuredMaxWait === Infinity) {
|
|
351
|
-
|
|
339
|
+
resolvedLazyRouteTimeout = finalTimeout;
|
|
352
340
|
DEBUG_BUILD && debug.log(
|
|
353
341
|
"[React Router] lazyRouteTimeout set to Infinity, capping at finalTimeout:",
|
|
354
342
|
finalTimeout,
|
|
@@ -356,7 +344,7 @@ function createReactRouterV6CompatibleTracingIntegration(options, version) {
|
|
|
356
344
|
);
|
|
357
345
|
} else if (Number.isNaN(configuredMaxWait)) {
|
|
358
346
|
DEBUG_BUILD && debug.warn("[React Router] lazyRouteTimeout must be a number, falling back to default:", defaultMaxWait);
|
|
359
|
-
|
|
347
|
+
resolvedLazyRouteTimeout = defaultMaxWait;
|
|
360
348
|
} else if (configuredMaxWait < 0) {
|
|
361
349
|
DEBUG_BUILD && debug.warn(
|
|
362
350
|
"[React Router] lazyRouteTimeout must be non-negative or Infinity, got:",
|
|
@@ -364,51 +352,51 @@ function createReactRouterV6CompatibleTracingIntegration(options, version) {
|
|
|
364
352
|
"falling back to:",
|
|
365
353
|
defaultMaxWait
|
|
366
354
|
);
|
|
367
|
-
|
|
355
|
+
resolvedLazyRouteTimeout = defaultMaxWait;
|
|
368
356
|
} else {
|
|
369
|
-
|
|
357
|
+
resolvedLazyRouteTimeout = configuredMaxWait;
|
|
358
|
+
}
|
|
359
|
+
if (typeof useLocation === "function" && typeof useNavigationType === "function" && typeof createRoutesFromChildren === "function" && typeof matchRoutes === "function") {
|
|
360
|
+
reactRouterConfigByClient.set(client, {
|
|
361
|
+
useLocation,
|
|
362
|
+
useNavigationType,
|
|
363
|
+
createRoutesFromChildren,
|
|
364
|
+
matchRoutes,
|
|
365
|
+
stripBasename: stripBasename || false,
|
|
366
|
+
enableAsyncRouteHandlers,
|
|
367
|
+
instrumentNavigation,
|
|
368
|
+
lazyRouteTimeout: resolvedLazyRouteTimeout,
|
|
369
|
+
lazyRouteManifest,
|
|
370
|
+
basename: ""
|
|
371
|
+
});
|
|
372
|
+
} else {
|
|
373
|
+
DEBUG_BUILD && debug.warn(
|
|
374
|
+
"[React Router] Skipping route instrumentation because `useLocation`, `useNavigationType`, `createRoutesFromChildren` or `matchRoutes` was not provided. Pass them to `reactRouterBrowserTracingIntegration`, or import it from `@sentry/react/react-router` to have them supplied automatically."
|
|
375
|
+
);
|
|
370
376
|
}
|
|
371
|
-
_useEffect = useEffect;
|
|
372
|
-
_useLocation = useLocation;
|
|
373
|
-
_useNavigationType = useNavigationType;
|
|
374
|
-
_matchRoutes = matchRoutes;
|
|
375
|
-
_createRoutesFromChildren = createRoutesFromChildren;
|
|
376
|
-
_enableAsyncRouteHandlers = enableAsyncRouteHandlers;
|
|
377
|
-
_lazyRouteManifest = lazyRouteManifest;
|
|
378
|
-
initializeRouterUtils(matchRoutes, stripBasename || false);
|
|
379
377
|
},
|
|
380
378
|
afterAllSetup(client) {
|
|
381
|
-
integration.afterAllSetup(client);
|
|
382
379
|
const initPathName = WINDOW.location?.pathname;
|
|
383
380
|
if (instrumentPageLoad && initPathName) {
|
|
384
381
|
startBrowserTracingPageLoadSpan(client, {
|
|
385
|
-
|
|
382
|
+
// With span streaming, span names have to be low cardinality. The route is only resolved
|
|
383
|
+
// once the router renders, which updates the span name then.
|
|
384
|
+
name: hasSpanStreamingEnabled(client) ? PAGELOAD_SPAN_NAME_FALLBACK : initPathName,
|
|
386
385
|
attributes: {
|
|
387
|
-
[
|
|
388
|
-
[
|
|
386
|
+
[SENTRY_SEGMENT_NAME_SOURCE]: "url",
|
|
387
|
+
[SENTRY_OP]: PAGELOAD,
|
|
389
388
|
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: `auto.pageload.react.reactrouter${version ? `_v${version}` : ""}`
|
|
390
389
|
}
|
|
391
390
|
});
|
|
392
391
|
}
|
|
393
|
-
if (instrumentNavigation) {
|
|
394
|
-
CLIENTS_WITH_INSTRUMENT_NAVIGATION.add(client);
|
|
395
|
-
}
|
|
396
392
|
}
|
|
397
|
-
};
|
|
393
|
+
});
|
|
398
394
|
}
|
|
399
395
|
function createV6CompatibleWrapUseRoutes(origUseRoutes, version) {
|
|
400
|
-
|
|
401
|
-
DEBUG_BUILD && debug.warn(
|
|
402
|
-
"reactRouterV6Instrumentation was unable to wrap `useRoutes` because of one or more missing parameters."
|
|
403
|
-
);
|
|
404
|
-
return origUseRoutes;
|
|
405
|
-
}
|
|
406
|
-
const SentryRoutes = (props) => {
|
|
396
|
+
const RouteReporter = ({ config, routes, locationArg }) => {
|
|
407
397
|
const isMountRenderPass = React.useRef(true);
|
|
408
|
-
const
|
|
409
|
-
const
|
|
410
|
-
const location = _useLocation();
|
|
411
|
-
const navigationType = _useNavigationType();
|
|
398
|
+
const location = config.useLocation();
|
|
399
|
+
const navigationType = config.useNavigationType();
|
|
412
400
|
const stableLocationParam = typeof locationArg === "string" || locationArg?.pathname ? locationArg : location;
|
|
413
401
|
useIsomorphicLayoutEffect(() => {
|
|
414
402
|
const added = addRoutesToAllRoutes(routes);
|
|
@@ -421,7 +409,8 @@ function createV6CompatibleWrapUseRoutes(origUseRoutes, version) {
|
|
|
421
409
|
activeRootSpan: getActiveRootSpan(),
|
|
422
410
|
location: normalizedLocation,
|
|
423
411
|
routes,
|
|
424
|
-
allRoutes: Array.from(allRoutes)
|
|
412
|
+
allRoutes: Array.from(allRoutes),
|
|
413
|
+
config
|
|
425
414
|
});
|
|
426
415
|
isMountRenderPass.current = false;
|
|
427
416
|
} else {
|
|
@@ -430,17 +419,26 @@ function createV6CompatibleWrapUseRoutes(origUseRoutes, version) {
|
|
|
430
419
|
routes,
|
|
431
420
|
navigationType,
|
|
432
421
|
version,
|
|
433
|
-
allRoutes: Array.from(allRoutes)
|
|
422
|
+
allRoutes: Array.from(allRoutes),
|
|
423
|
+
config
|
|
434
424
|
});
|
|
435
425
|
}
|
|
436
426
|
}, [navigationType, stableLocationParam]);
|
|
437
|
-
return
|
|
427
|
+
return null;
|
|
428
|
+
};
|
|
429
|
+
const SentryRoutesWrapper = ({
|
|
430
|
+
routes,
|
|
431
|
+
locationArg
|
|
432
|
+
}) => {
|
|
433
|
+
const config = getRouterConfig(getClient());
|
|
434
|
+
const routesElement = origUseRoutes(routes, locationArg);
|
|
435
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, routesElement, config ? /* @__PURE__ */ React.createElement(RouteReporter, { config, routes, locationArg }) : null);
|
|
438
436
|
};
|
|
439
437
|
return (routes, locationArg) => {
|
|
440
|
-
return /* @__PURE__ */ React.createElement(
|
|
438
|
+
return /* @__PURE__ */ React.createElement(SentryRoutesWrapper, { routes, locationArg });
|
|
441
439
|
};
|
|
442
440
|
}
|
|
443
|
-
function wrapPatchRoutesOnNavigation(opts, isMemoryRouter
|
|
441
|
+
function wrapPatchRoutesOnNavigation(opts, isMemoryRouter, capturedSpan, config) {
|
|
444
442
|
if (!opts || !("patchRoutesOnNavigation" in opts) || typeof opts.patchRoutesOnNavigation !== "function") {
|
|
445
443
|
return opts || {};
|
|
446
444
|
}
|
|
@@ -472,14 +470,14 @@ function wrapPatchRoutesOnNavigation(opts, isMemoryRouter = false, capturedSpan)
|
|
|
472
470
|
}
|
|
473
471
|
}
|
|
474
472
|
const spanJson = activeRootSpan ? spanToJSON(activeRootSpan) : void 0;
|
|
475
|
-
if (targetPath && activeRootSpan && spanJson && !spanJson.
|
|
476
|
-
spanJson.
|
|
473
|
+
if (targetPath && activeRootSpan && spanJson && !spanJson.end_timestamp && // Span hasn't ended yet
|
|
474
|
+
spanJson.attributes[SENTRY_OP] === "navigation") {
|
|
477
475
|
updateNavigationSpan(
|
|
478
476
|
activeRootSpan,
|
|
479
477
|
{ pathname: targetPath, search: "", hash: "", state: null, key: "default" },
|
|
480
478
|
Array.from(allRoutes),
|
|
481
479
|
true,
|
|
482
|
-
|
|
480
|
+
config
|
|
483
481
|
);
|
|
484
482
|
}
|
|
485
483
|
return originalPatch(routeId, children);
|
|
@@ -498,8 +496,8 @@ function wrapPatchRoutesOnNavigation(opts, isMemoryRouter = false, capturedSpan)
|
|
|
498
496
|
}
|
|
499
497
|
}
|
|
500
498
|
const spanJson = activeRootSpan ? spanToJSON(activeRootSpan) : void 0;
|
|
501
|
-
if (activeRootSpan && spanJson && !spanJson.
|
|
502
|
-
spanJson.
|
|
499
|
+
if (activeRootSpan && spanJson && !spanJson.end_timestamp && // Span hasn't ended yet
|
|
500
|
+
spanJson.attributes[SENTRY_OP] === "navigation") {
|
|
503
501
|
const pathname = targetPath;
|
|
504
502
|
if (pathname) {
|
|
505
503
|
updateNavigationSpan(
|
|
@@ -507,7 +505,7 @@ function wrapPatchRoutesOnNavigation(opts, isMemoryRouter = false, capturedSpan)
|
|
|
507
505
|
{ pathname, search: "", hash: "", state: null, key: "default" },
|
|
508
506
|
Array.from(allRoutes),
|
|
509
507
|
false,
|
|
510
|
-
|
|
508
|
+
config
|
|
511
509
|
);
|
|
512
510
|
}
|
|
513
511
|
}
|
|
@@ -521,14 +519,14 @@ function wrapPatchRoutesOnNavigation(opts, isMemoryRouter = false, capturedSpan)
|
|
|
521
519
|
};
|
|
522
520
|
}
|
|
523
521
|
function handleNavigation(opts) {
|
|
524
|
-
const { location, routes, navigationType, version,
|
|
525
|
-
const branches = Array.isArray(matches) ? matches :
|
|
522
|
+
const { location, routes, navigationType, version, config, matches, allRoutes: allRoutes2 } = opts;
|
|
523
|
+
const branches = Array.isArray(matches) ? matches : config.matchRoutes(allRoutes2 || routes, location, config.basename);
|
|
526
524
|
const client = getClient();
|
|
527
|
-
if (!client || !
|
|
525
|
+
if (!client || !config.instrumentNavigation) {
|
|
528
526
|
return;
|
|
529
527
|
}
|
|
530
528
|
const activeRootSpan = getActiveRootSpan();
|
|
531
|
-
if (activeRootSpan && spanToJSON(activeRootSpan).
|
|
529
|
+
if (activeRootSpan && spanToJSON(activeRootSpan).attributes[SENTRY_OP] === "pageload" && navigationType === "POP") {
|
|
532
530
|
return;
|
|
533
531
|
}
|
|
534
532
|
if ((navigationType === "PUSH" || navigationType === "POP") && branches) {
|
|
@@ -537,13 +535,11 @@ function handleNavigation(opts) {
|
|
|
537
535
|
allRoutes2 || routes,
|
|
538
536
|
allRoutes2 || routes,
|
|
539
537
|
branches,
|
|
540
|
-
|
|
541
|
-
_lazyRouteManifest,
|
|
542
|
-
_enableAsyncRouteHandlers
|
|
538
|
+
config
|
|
543
539
|
);
|
|
544
540
|
const locationKey = computeLocationKey(location);
|
|
545
541
|
const trackedNav = activeNavigationSpans.get(client);
|
|
546
|
-
const trackedSpanHasEnded = trackedNav && !trackedNav.isPlaceholder ? !!spanToJSON(trackedNav.span).
|
|
542
|
+
const trackedSpanHasEnded = trackedNav && !trackedNav.isPlaceholder ? !!spanToJSON(trackedNav.span).end_timestamp : false;
|
|
547
543
|
const { skip, shouldUpdate } = shouldSkipNavigation(trackedNav, locationKey, name, trackedSpanHasEnded);
|
|
548
544
|
if (skip) {
|
|
549
545
|
if (shouldUpdate && trackedNav) {
|
|
@@ -554,16 +550,13 @@ function handleNavigation(opts) {
|
|
|
554
550
|
`[Tracing] Updated placeholder navigation name from "${oldName}" to "${name}" (will apply to real span)`
|
|
555
551
|
);
|
|
556
552
|
} else {
|
|
557
|
-
|
|
558
|
-
trackedNav.span.
|
|
553
|
+
const isUnparameterizedStreamedNavigation = source !== "route" && hasSpanStreamingEnabled(client);
|
|
554
|
+
trackedNav.span.updateName(isUnparameterizedStreamedNavigation ? NAVIGATION_SPAN_NAME_FALLBACK : name);
|
|
555
|
+
trackedNav.span.setAttribute(SENTRY_SEGMENT_NAME_SOURCE, source);
|
|
559
556
|
if (source === "route") {
|
|
560
557
|
trackedNav.span.setAttribute(URL_TEMPLATE, name);
|
|
561
558
|
}
|
|
562
|
-
addNonEnumerableProperty(
|
|
563
|
-
trackedNav.span,
|
|
564
|
-
"__sentry_navigation_name_set__",
|
|
565
|
-
true
|
|
566
|
-
);
|
|
559
|
+
addNonEnumerableProperty(trackedNav.span, "__sentry_navigation_name_set__", true);
|
|
567
560
|
trackedNav.routeName = name;
|
|
568
561
|
DEBUG_BUILD && debug.log(`[Tracing] Updated navigation span name from "${oldName}" to "${name}"`);
|
|
569
562
|
}
|
|
@@ -585,11 +578,12 @@ function handleNavigation(opts) {
|
|
|
585
578
|
let navigationSpan;
|
|
586
579
|
try {
|
|
587
580
|
navigationSpan = startBrowserTracingNavigationSpan(client, {
|
|
588
|
-
|
|
589
|
-
//
|
|
581
|
+
// Use placeholder's routeName in case it was updated. With span streaming, span names have to
|
|
582
|
+
// be low cardinality, so we can't fall back to the URL.
|
|
583
|
+
name: source === "route" || !hasSpanStreamingEnabled(client) ? placeholderEntry.routeName : NAVIGATION_SPAN_NAME_FALLBACK,
|
|
590
584
|
attributes: {
|
|
591
|
-
[
|
|
592
|
-
[
|
|
585
|
+
[SENTRY_SEGMENT_NAME_SOURCE]: source,
|
|
586
|
+
[SENTRY_OP]: NAVIGATION,
|
|
593
587
|
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: `auto.navigation.react.reactrouter${version ? `_v${version}` : ""}`,
|
|
594
588
|
...source === "route" && { [URL_TEMPLATE]: placeholderEntry.routeName }
|
|
595
589
|
}
|
|
@@ -599,6 +593,7 @@ function handleNavigation(opts) {
|
|
|
599
593
|
throw e;
|
|
600
594
|
}
|
|
601
595
|
if (navigationSpan) {
|
|
596
|
+
addNonEnumerableProperty(navigationSpan, "__sentry_navigation_pathname__", location.pathname);
|
|
602
597
|
activeNavigationSpans.set(client, {
|
|
603
598
|
span: navigationSpan,
|
|
604
599
|
routeName: placeholderEntry.routeName,
|
|
@@ -606,7 +601,7 @@ function handleNavigation(opts) {
|
|
|
606
601
|
pathname: location.pathname,
|
|
607
602
|
locationKey
|
|
608
603
|
});
|
|
609
|
-
patchSpanEnd(navigationSpan, location, routes,
|
|
604
|
+
patchSpanEnd(navigationSpan, location, routes, "navigation", config);
|
|
610
605
|
} else {
|
|
611
606
|
activeNavigationSpans.delete(client);
|
|
612
607
|
}
|
|
@@ -646,32 +641,32 @@ function updatePageloadTransaction({
|
|
|
646
641
|
activeRootSpan,
|
|
647
642
|
location,
|
|
648
643
|
routes,
|
|
644
|
+
config,
|
|
649
645
|
matches,
|
|
650
|
-
basename,
|
|
651
646
|
allRoutes: allRoutes2
|
|
652
647
|
}) {
|
|
653
|
-
const branches = Array.isArray(matches) ? matches :
|
|
648
|
+
const branches = Array.isArray(matches) ? matches : config.matchRoutes(allRoutes2 || routes, location, config.basename);
|
|
654
649
|
if (branches) {
|
|
655
650
|
const [name, source] = resolveRouteNameAndSource(
|
|
656
651
|
location,
|
|
657
652
|
allRoutes2 || routes,
|
|
658
653
|
allRoutes2 || routes,
|
|
659
654
|
branches,
|
|
660
|
-
|
|
661
|
-
_lazyRouteManifest,
|
|
662
|
-
_enableAsyncRouteHandlers
|
|
655
|
+
config
|
|
663
656
|
);
|
|
664
657
|
getCurrentScope().setTransactionName(name || "/");
|
|
665
658
|
if (activeRootSpan) {
|
|
666
|
-
|
|
667
|
-
|
|
659
|
+
const client = getClient();
|
|
660
|
+
const isUnparameterizedStreamedPageload = source !== "route" && !!client && hasSpanStreamingEnabled(client);
|
|
661
|
+
activeRootSpan.updateName(isUnparameterizedStreamedPageload ? PAGELOAD_SPAN_NAME_FALLBACK : name);
|
|
662
|
+
activeRootSpan.setAttribute(SENTRY_SEGMENT_NAME_SOURCE, source);
|
|
668
663
|
if (source === "route") {
|
|
669
664
|
activeRootSpan.setAttribute(URL_TEMPLATE, name);
|
|
670
665
|
}
|
|
671
|
-
patchSpanEnd(activeRootSpan, location, routes,
|
|
666
|
+
patchSpanEnd(activeRootSpan, location, routes, "pageload", config);
|
|
672
667
|
}
|
|
673
668
|
} else if (activeRootSpan) {
|
|
674
|
-
patchSpanEnd(activeRootSpan, location, routes,
|
|
669
|
+
patchSpanEnd(activeRootSpan, location, routes, "pageload", config);
|
|
675
670
|
}
|
|
676
671
|
}
|
|
677
672
|
function shouldUpdateWildcardSpanName(currentName, currentSource, newName, newSource, allowNoCurrentName = false) {
|
|
@@ -690,32 +685,27 @@ function shouldUpdateWildcardSpanName(currentName, currentSource, newName, newSo
|
|
|
690
685
|
}
|
|
691
686
|
return false;
|
|
692
687
|
}
|
|
693
|
-
function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes,
|
|
688
|
+
function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, spanType, allRoutes2, config) {
|
|
694
689
|
try {
|
|
695
|
-
const currentSource = spanJson.
|
|
690
|
+
const currentSource = spanJson.attributes[SENTRY_SEGMENT_NAME_SOURCE];
|
|
696
691
|
if (currentSource === "route" && currentName && !transactionNameHasWildcard(currentName)) {
|
|
697
692
|
return;
|
|
698
693
|
}
|
|
699
694
|
const currentAllRoutes = Array.from(allRoutes2);
|
|
700
695
|
const routesToUse = currentAllRoutes.length > 0 ? currentAllRoutes : routes;
|
|
701
|
-
const branches =
|
|
696
|
+
const branches = config.matchRoutes(routesToUse, location, config.basename);
|
|
702
697
|
if (!branches) {
|
|
703
698
|
return;
|
|
704
699
|
}
|
|
705
|
-
const [name, source] = resolveRouteNameAndSource(
|
|
706
|
-
location,
|
|
707
|
-
routesToUse,
|
|
708
|
-
routesToUse,
|
|
709
|
-
branches,
|
|
710
|
-
basename,
|
|
711
|
-
_lazyRouteManifest,
|
|
712
|
-
_enableAsyncRouteHandlers
|
|
713
|
-
);
|
|
700
|
+
const [name, source] = resolveRouteNameAndSource(location, routesToUse, routesToUse, branches, config);
|
|
714
701
|
const isImprovement = shouldUpdateWildcardSpanName(currentName, currentSource, name, source, true);
|
|
715
|
-
const spanNotEnded = spanType === "pageload" || !spanJson.
|
|
702
|
+
const spanNotEnded = spanType === "pageload" || !spanJson.end_timestamp;
|
|
716
703
|
if (isImprovement && spanNotEnded) {
|
|
717
|
-
|
|
718
|
-
|
|
704
|
+
const client = getClient();
|
|
705
|
+
const isUnparameterizedStreamedSpan = source !== "route" && !!client && hasSpanStreamingEnabled(client);
|
|
706
|
+
const fallbackName = spanType === "pageload" ? PAGELOAD_SPAN_NAME_FALLBACK : NAVIGATION_SPAN_NAME_FALLBACK;
|
|
707
|
+
span.updateName(isUnparameterizedStreamedSpan ? fallbackName : name);
|
|
708
|
+
span.setAttribute(SENTRY_SEGMENT_NAME_SOURCE, source);
|
|
719
709
|
if (source === "route") {
|
|
720
710
|
span.setAttribute(URL_TEMPLATE, name);
|
|
721
711
|
}
|
|
@@ -724,7 +714,7 @@ function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, route
|
|
|
724
714
|
DEBUG_BUILD && debug.warn(`Error updating span details before ending: ${error}`);
|
|
725
715
|
}
|
|
726
716
|
}
|
|
727
|
-
function patchSpanEnd(span, location, routes,
|
|
717
|
+
function patchSpanEnd(span, location, routes, spanType, config) {
|
|
728
718
|
const patchedPropertyName = `__sentry_${spanType}_end_patched__`;
|
|
729
719
|
const hasEndBeenPatched = span?.[patchedPropertyName];
|
|
730
720
|
if (hasEndBeenPatched || !span.end) {
|
|
@@ -739,13 +729,13 @@ function patchSpanEnd(span, location, routes, basename, spanType) {
|
|
|
739
729
|
endCalled = true;
|
|
740
730
|
const endTimestamp = args.length > 0 ? args[0] : Date.now() / 1e3;
|
|
741
731
|
const spanJson = spanToJSON(span);
|
|
742
|
-
const currentName = spanJson.
|
|
743
|
-
const currentSource = spanJson.
|
|
732
|
+
const currentName = spanJson.name;
|
|
733
|
+
const currentSource = spanJson.attributes[SENTRY_SEGMENT_NAME_SOURCE];
|
|
744
734
|
const cleanupNavigationSpan = () => {
|
|
745
735
|
const client = getClient();
|
|
746
736
|
if (client && spanType === "navigation") {
|
|
747
737
|
const trackedNav = activeNavigationSpans.get(client);
|
|
748
|
-
if (trackedNav
|
|
738
|
+
if (trackedNav?.span === span) {
|
|
749
739
|
activeNavigationSpans.delete(client);
|
|
750
740
|
}
|
|
751
741
|
}
|
|
@@ -755,18 +745,18 @@ function patchSpanEnd(span, location, routes, basename, spanType) {
|
|
|
755
745
|
const hasPendingOrMayHaveLazyRoutes = pendingPromises && pendingPromises.size > 0 || mayHaveLazyRoutes;
|
|
756
746
|
const shouldWaitForLazyRoutes = hasPendingOrMayHaveLazyRoutes && currentName && (transactionNameHasWildcard(currentName) || currentSource !== "route");
|
|
757
747
|
if (shouldWaitForLazyRoutes) {
|
|
758
|
-
if (
|
|
759
|
-
tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes,
|
|
748
|
+
if (config.lazyRouteTimeout === 0) {
|
|
749
|
+
tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, spanType, allRoutes, config);
|
|
760
750
|
cleanupNavigationSpan();
|
|
761
751
|
originalEnd(endTimestamp);
|
|
762
752
|
return;
|
|
763
753
|
}
|
|
764
|
-
const timeoutPromise = new Promise((r) => setTimeout(r,
|
|
754
|
+
const timeoutPromise = new Promise((r) => setTimeout(r, config.lazyRouteTimeout));
|
|
765
755
|
let waitPromise;
|
|
766
756
|
if (pendingPromises && pendingPromises.size > 0) {
|
|
767
757
|
const allSettled = Promise.allSettled(pendingPromises).then(() => {
|
|
768
758
|
});
|
|
769
|
-
waitPromise =
|
|
759
|
+
waitPromise = config.lazyRouteTimeout === Infinity ? allSettled : Promise.race([allSettled, timeoutPromise]);
|
|
770
760
|
} else {
|
|
771
761
|
waitPromise = timeoutPromise;
|
|
772
762
|
}
|
|
@@ -775,12 +765,12 @@ function patchSpanEnd(span, location, routes, basename, spanType) {
|
|
|
775
765
|
tryUpdateSpanNameBeforeEnd(
|
|
776
766
|
span,
|
|
777
767
|
updatedSpanJson,
|
|
778
|
-
updatedSpanJson.
|
|
768
|
+
updatedSpanJson.name,
|
|
779
769
|
location,
|
|
780
770
|
routes,
|
|
781
|
-
basename,
|
|
782
771
|
spanType,
|
|
783
|
-
allRoutes
|
|
772
|
+
allRoutes,
|
|
773
|
+
config
|
|
784
774
|
);
|
|
785
775
|
cleanupNavigationSpan();
|
|
786
776
|
originalEnd(endTimestamp);
|
|
@@ -790,24 +780,23 @@ function patchSpanEnd(span, location, routes, basename, spanType) {
|
|
|
790
780
|
});
|
|
791
781
|
return;
|
|
792
782
|
}
|
|
793
|
-
tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes,
|
|
783
|
+
tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, spanType, allRoutes, config);
|
|
794
784
|
cleanupNavigationSpan();
|
|
795
785
|
originalEnd(endTimestamp);
|
|
796
786
|
};
|
|
797
787
|
addNonEnumerableProperty(span, patchedPropertyName, true);
|
|
798
788
|
}
|
|
799
789
|
function createV6CompatibleWithSentryReactRouterRouting(Routes, version) {
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
return Routes;
|
|
805
|
-
}
|
|
806
|
-
const SentryRoutes = (props) => {
|
|
790
|
+
const RouteReporter = ({
|
|
791
|
+
config,
|
|
792
|
+
routeChildren
|
|
793
|
+
}) => {
|
|
807
794
|
const isMountRenderPass = React.useRef(true);
|
|
808
|
-
const location =
|
|
809
|
-
const navigationType =
|
|
810
|
-
const routes =
|
|
795
|
+
const location = config.useLocation();
|
|
796
|
+
const navigationType = config.useNavigationType();
|
|
797
|
+
const routes = config.createRoutesFromChildren(
|
|
798
|
+
routeChildren
|
|
799
|
+
);
|
|
811
800
|
useIsomorphicLayoutEffect(() => {
|
|
812
801
|
const added = addRoutesToAllRoutes(routes);
|
|
813
802
|
return () => removeRoutesFromAllRoutes(added);
|
|
@@ -819,17 +808,36 @@ function createV6CompatibleWithSentryReactRouterRouting(Routes, version) {
|
|
|
819
808
|
activeRootSpan: getActiveRootSpan(),
|
|
820
809
|
location,
|
|
821
810
|
routes,
|
|
822
|
-
allRoutes: Array.from(allRoutes)
|
|
811
|
+
allRoutes: Array.from(allRoutes),
|
|
812
|
+
config
|
|
823
813
|
});
|
|
824
814
|
isMountRenderPass.current = false;
|
|
825
815
|
} else {
|
|
826
|
-
handleNavigation({
|
|
816
|
+
handleNavigation({
|
|
817
|
+
location,
|
|
818
|
+
routes,
|
|
819
|
+
navigationType,
|
|
820
|
+
version,
|
|
821
|
+
allRoutes: Array.from(allRoutes),
|
|
822
|
+
config
|
|
823
|
+
});
|
|
827
824
|
}
|
|
828
825
|
},
|
|
829
826
|
// Re-run only on location/navigation changes, not children changes
|
|
830
827
|
[location, navigationType]
|
|
831
828
|
);
|
|
832
|
-
return
|
|
829
|
+
return null;
|
|
830
|
+
};
|
|
831
|
+
const SentryRoutes = (props) => {
|
|
832
|
+
const config = getRouterConfig(getClient());
|
|
833
|
+
return /* @__PURE__ */ React.createElement(
|
|
834
|
+
React.Fragment,
|
|
835
|
+
null,
|
|
836
|
+
// @ts-expect-error Setting more specific React Component typing for `R` generic above
|
|
837
|
+
// will break advanced type inference done by react router params
|
|
838
|
+
/* @__PURE__ */ React.createElement(Routes, { ...props }),
|
|
839
|
+
config ? /* @__PURE__ */ React.createElement(RouteReporter, { config, routeChildren: props.children }) : null
|
|
840
|
+
);
|
|
833
841
|
};
|
|
834
842
|
hoistNonReactStatics(SentryRoutes, Routes);
|
|
835
843
|
return SentryRoutes;
|