import { _nullishCoalesce, _optionalChain } from '@sentry/utils'; import { addTracingExtensions, withIsolationScope, continueTrace, startSpan, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, handleCallbackErrors, captureException, setHttpStatus } from '@sentry/core'; import { winterCGHeadersToDict } from '@sentry/utils'; import { isRedirectNavigationError } from './nextNavigationErrorUtils.js'; import { platformSupportsStreaming } from './utils/platformSupportsStreaming.js'; import { flushQueue } from './utils/responseEnd.js'; /** * Wraps a Next.js route handler with performance and error instrumentation. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any function wrapRouteHandlerWithSentry( routeHandler, context, ) { addTracingExtensions(); // eslint-disable-next-line deprecation/deprecation const { method, parameterizedRoute, baggageHeader, sentryTraceHeader, headers } = context; return new Proxy(routeHandler, { apply: (originalFunction, thisArg, args) => { return withIsolationScope(async isolationScope => { isolationScope.setSDKProcessingMetadata({ request: { headers: headers ? winterCGHeadersToDict(headers) : undefined, }, }); return continueTrace( { sentryTrace: _nullishCoalesce(_nullishCoalesce(sentryTraceHeader, () => ( _optionalChain([headers, 'optionalAccess', _ => _.get, 'call', _2 => _2('sentry-trace')]))), () => ( undefined)), baggage: _nullishCoalesce(baggageHeader, () => ( _optionalChain([headers, 'optionalAccess', _3 => _3.get, 'call', _4 => _4('baggage')]))), }, async () => { try { return await startSpan( { op: 'http.server', name: `${method} ${parameterizedRoute}`, attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.nextjs', }, }, async span => { const response = await handleCallbackErrors( () => originalFunction.apply(thisArg, args), error => { // Next.js throws errors when calling `redirect()`. We don't wanna report these. if (!isRedirectNavigationError(error)) { captureException(error, { mechanism: { handled: false, }, }); } }, ); try { span && setHttpStatus(span, response.status); } catch (e) { // best effort - response may be undefined? } return response; }, ); } finally { if (!platformSupportsStreaming() || process.env.NEXT_RUNTIME === 'edge') { // 1. Edge transport requires manual flushing // 2. Lambdas require manual flushing to prevent execution freeze before the event is sent await flushQueue(); } } }, ); }); }, }); } export { wrapRouteHandlerWithSentry }; //# sourceMappingURL=wrapRouteHandlerWithSentry.js.map