Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); const browser = require('@sentry/browser'); const core = require('@sentry/core'); const debugBuild = require('../debug-build.js'); const utils = require('./utils.js'); /** * Captures location at invocation time. Prefers navigation context over window.location * since window.location hasn't updated yet when async handlers are invoked. * * When inside a patchRoutesOnNavigation call, uses the captured targetPath. If targetPath * is undefined (patchRoutesOnNavigation can be invoked without a path argument), returns * null rather than falling back to WINDOW.location which could be stale/wrong after the * user navigated away during async loading. Returning null causes the span name update * to be skipped, which is safer than using incorrect location data. */ function captureCurrentLocation() { const navContext = utils.getNavigationContext(); if (navContext) { if (navContext.targetPath) { return { pathname: navContext.targetPath, search: '', hash: '', state: null, key: 'default', }; } // Don't fall back to potentially stale WINDOW.location return null; } if (typeof browser.WINDOW !== 'undefined') { try { const windowLocation = browser.WINDOW.location; if (windowLocation) { return { pathname: windowLocation.pathname, search: windowLocation.search || '', hash: windowLocation.hash || '', state: null, key: 'default', }; } } catch { debugBuild.DEBUG_BUILD && core.debug.warn('[React Router] Could not access window.location'); } } return null; } /** * Captures the active span at invocation time. Prefers navigation context span * to ensure we update the correct span even if another navigation starts. */ function captureActiveSpan() { const navContext = utils.getNavigationContext(); if (navContext) { return navContext.span; } return utils.getActiveRootSpan(); } /** * Creates a proxy wrapper for an async handler function. * Captures both the location and the active span at invocation time to ensure * the correct span is updated when the handler resolves. */ function createAsyncHandlerProxy( originalFunction, route, handlerKey, processResolvedRoutes , ) { const proxy = new Proxy(originalFunction, { apply(target, thisArg, argArray) { const locationAtInvocation = captureCurrentLocation(); const spanAtInvocation = captureActiveSpan(); const result = target.apply(thisArg, argArray); handleAsyncHandlerResult( result, route, handlerKey, processResolvedRoutes, locationAtInvocation, spanAtInvocation, ); return result; }, }); core.addNonEnumerableProperty(proxy, '__sentry_proxied__', true); return proxy; } /** * Handles the result of an async handler function call. * Passes the captured span through to ensure the correct span is updated. */ function handleAsyncHandlerResult( result, route, handlerKey, processResolvedRoutes , currentLocation, capturedSpan, ) { if (core.isThenable(result)) { (result ) .then((resolvedRoutes) => { if (Array.isArray(resolvedRoutes)) { processResolvedRoutes(resolvedRoutes, route, currentLocation ?? undefined, capturedSpan); } }) .catch((e) => { debugBuild.DEBUG_BUILD && core.debug.warn(`Error resolving async handler '${handlerKey}' for route`, route, e); }); } else if (Array.isArray(result)) { processResolvedRoutes(result, route, currentLocation ?? undefined, capturedSpan); } } /** * Recursively checks a route for async handlers and sets up Proxies to add discovered child routes to allRoutes when called. */ function checkRouteForAsyncHandler( route, processResolvedRoutes , ) { // Set up proxies for any functions in the route's handle if (route.handle && typeof route.handle === 'object') { for (const key of Object.keys(route.handle)) { const maybeFn = route.handle[key]; if (typeof maybeFn === 'function' && !(maybeFn ).__sentry_proxied__) { route.handle[key] = createAsyncHandlerProxy(maybeFn, route, key, processResolvedRoutes); } } } // Recursively check child routes if (Array.isArray(route.children)) { for (const child of route.children) { checkRouteForAsyncHandler(child, processResolvedRoutes); } } } exports.checkRouteForAsyncHandler = checkRouteForAsyncHandler; exports.createAsyncHandlerProxy = createAsyncHandlerProxy; exports.handleAsyncHandlerResult = handleAsyncHandlerResult; //# sourceMappingURL=lazy-routes.js.map