diff --git a/packages/angular/src/tracing.ts b/packages/angular/src/tracing.ts index c45c3d7f4185..de631c36e679 100644 --- a/packages/angular/src/tracing.ts +++ b/packages/angular/src/tracing.ts @@ -25,8 +25,10 @@ import { CODE_FUNCTION_NAME, SENTRY_OP, URL_FULL, URL_PATH, URL_TEMPLATE } from import { FUNCTION } from '@sentry/conventions/op'; import type { Integration, Span } from '@sentry/core'; import { + createCachedRouteProvider, debug, parseStringToURLObject, + setRouteProvider, stripUrlQueryAndFragment, timestampInSeconds, filterCollectedUrl, @@ -40,6 +42,11 @@ import { runOutsideAngular } from './zone'; let instrumentationInitialized: boolean; +// The parameterized route only exists on Angular's `ResolveEnd` event, resolved from the router +// state snapshot, so there is no matcher the integration could call. `TraceService` records each +// route as it resolves and the provider answers from that. +const ROUTE_PROVIDER = createCachedRouteProvider(); + /** * A custom browser tracing integration for Angular. * @@ -54,10 +61,18 @@ export function browserTracingIntegration( instrumentationInitialized = true; } - return originalBrowserTracingIntegration({ + const integration = originalBrowserTracingIntegration({ ...options, instrumentNavigation: false, }); + + return { + ...integration, + setup(client) { + setRouteProvider(ROUTE_PROVIDER, client); + integration.setup?.(client); + }, + }; } /** @@ -171,6 +186,7 @@ export class TraceService implements OnDestroy { ); if (route) { + ROUTE_PROVIDER.record(stripUrlQueryAndFragment(event.urlAfterRedirects), route); getCurrentScope().setTransactionName(route); }