diff --git a/dev-packages/e2e-tests/test-applications/astro-5/tests/tracing.dynamic.test.ts b/dev-packages/e2e-tests/test-applications/astro-5/tests/tracing.dynamic.test.ts index 66f9e9595920..b7dda807c65c 100644 --- a/dev-packages/e2e-tests/test-applications/astro-5/tests/tracing.dynamic.test.ts +++ b/dev-packages/e2e-tests/test-applications/astro-5/tests/tracing.dynamic.test.ts @@ -248,7 +248,7 @@ test.describe('nested SSR routes (client, server, server request)', () => { // Server HTTP request transaction expect(serverHTTPServerRequestTxn).toMatchObject({ - transaction: 'GET /api/user/myUsername123.json', // fixme: should be GET /api/user/[userId].json + transaction: 'GET /api/user/[userId].json', transaction_info: { source: 'route' }, contexts: { trace: { @@ -278,13 +278,13 @@ test.describe('nested SSR routes (client, server, server request)', () => { await page.goto('/catchAll/hell0/whatever-do'); const routeNameMetaContent = await page.locator('meta[name="sentry-route-name"]').getAttribute('content'); - expect(routeNameMetaContent).toBe('%2FcatchAll%2F%5Bpath%5D'); // fixme: should be %2FcatchAll%2F%5B...path%5D + expect(routeNameMetaContent).toBe('%2FcatchAll%2F%5B...path%5D'); const clientPageloadTxn = await clientPageloadTxnPromise; const serverPageRequestTxn = await serverPageRequestTxnPromise; expect(clientPageloadTxn).toMatchObject({ - transaction: '/catchAll/[path]', // fixme: should be /catchAll/[...path] + transaction: '/catchAll/[...path]', transaction_info: { source: 'route' }, contexts: { trace: { @@ -300,7 +300,7 @@ test.describe('nested SSR routes (client, server, server request)', () => { }); expect(serverPageRequestTxn).toMatchObject({ - transaction: 'GET /catchAll/[path]', // fixme: should be GET /catchAll/[...path] + transaction: 'GET /catchAll/[...path]', transaction_info: { source: 'route' }, contexts: { trace: { diff --git a/packages/astro/src/server/middleware.ts b/packages/astro/src/server/middleware.ts index 9f04d5427fcf..19aa11af0767 100644 --- a/packages/astro/src/server/middleware.ts +++ b/packages/astro/src/server/middleware.ts @@ -22,8 +22,7 @@ import { startSpan, withIsolationScope, } from '@sentry/node'; -import type { APIContext, MiddlewareResponseHandler } from 'astro'; -import type { ResolvedRouteWithCasedPattern } from '../integration/types'; +import type { APIContext, MiddlewareResponseHandler, RoutePart } from 'astro'; type MiddlewareOptions = { /** @@ -96,9 +95,6 @@ async function instrumentRequest( addNonEnumerableProperty(locals, '__sentry_wrapped__', true); } - const storedBuildTimeRoutes = (globalThis as unknown as { __sentryRouteInfo?: ResolvedRouteWithCasedPattern[] }) - ?.__sentryRouteInfo; - const isDynamicPageRequest = checkIsDynamicPageRequest(ctx); const request = ctx.request; @@ -135,10 +131,21 @@ async function instrumentRequest( // `routePattern` is available after Astro 5 const contextWithRoutePattern = ctx as Parameters[0] & { routePattern?: string }; const rawRoutePattern = contextWithRoutePattern.routePattern; - const foundRoute = storedBuildTimeRoutes?.find(route => route.pattern === rawRoutePattern); + + // @ts-expect-error Implicit any on Symbol.for (This is available in Astro 5) + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + const routesFromManifest = ctx?.[Symbol.for('context.routes')]?.manifest?.routes; + + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + const matchedRouteSegmentsFromManifest = routesFromManifest?.find( + (route: { routeData?: { route?: string } }) => route?.routeData?.route === rawRoutePattern, + )?.routeData?.segments; const parametrizedRoute = - foundRoute?.patternCaseSensitive || interpolateRouteFromUrlAndParams(ctx.url.pathname, ctx.params); + // Astro v5 - Joining the segments to get the correct casing of the parametrized route + (matchedRouteSegmentsFromManifest && joinRouteSegments(matchedRouteSegmentsFromManifest)) || + // Fallback (Astro v4 and earlier) + interpolateRouteFromUrlAndParams(ctx.url.pathname, ctx.params); const source = parametrizedRoute ? 'route' : 'url'; // storing res in a variable instead of directly returning is necessary to @@ -365,3 +372,18 @@ function checkIsDynamicPageRequest(context: Parameters + segment.map(routePart => (routePart.dynamic ? `[${routePart.content}]` : routePart.content)).join(''), + ); + + return `/${parthArray.join('/')}`; +}