UNPKG

@sentry/nextjs

Version:
90 lines (87 loc) 3.84 kB
import { withIsolationScope, getCurrentScope, winterCGRequestToRequestData, parseStringToURLObject, isURLObjectRelative, getActiveSpan, getRootSpan, spanToJSON, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, SEMANTIC_ATTRIBUTE_SENTRY_OP, setCapturedScopesOnSpan, startSpan, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, handleCallbackErrors, captureException } from '@sentry/core'; import { addHeadersAsAttributes } from '../common/utils/addHeadersAsAttributes.js'; import { waitUntil, flushSafelyWithTimeout } from '../common/utils/responseEnd.js'; import { URL_PATH, URL_FULL, HTTP_ROUTE } from '@sentry/conventions/attributes'; function wrapApiHandlerWithSentry(handler, parameterizedRoute) { return new Proxy(handler, { apply: async (wrappingTarget, thisArg, args) => { return withIsolationScope((isolationScope) => { const req = args[0]; const currentScope = getCurrentScope(); let headerAttributes = {}; if (req instanceof Request) { isolationScope.setSDKProcessingMetadata({ normalizedRequest: winterCGRequestToRequestData(req) }); currentScope.setTransactionName(`${req.method} ${parameterizedRoute}`); headerAttributes = addHeadersAsAttributes(req.headers); } else { currentScope.setTransactionName(`handler (${parameterizedRoute})`); } let spanName; let op = "http.server"; const urlObject = req instanceof Request ? parseStringToURLObject(req.url) : void 0; const urlAttributes = { [URL_FULL]: urlObject && !isURLObjectRelative(urlObject) ? urlObject.href : void 0, [URL_PATH]: urlObject?.pathname }; const activeSpan = getActiveSpan(); if (activeSpan) { spanName = `handler (${parameterizedRoute})`; op = void 0; const rootSpan = getRootSpan(activeSpan); if (rootSpan) { const rootSpanAttributes = spanToJSON(rootSpan).data; rootSpan.updateName( req instanceof Request ? `${req.method} ${parameterizedRoute}` : `handler ${parameterizedRoute}` ); rootSpan.setAttributes({ [SEMANTIC_ATTRIBUTE_SENTRY_OP]: "http.server", [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "route", [URL_FULL]: rootSpanAttributes[URL_FULL] ?? urlAttributes[URL_FULL], [URL_PATH]: rootSpanAttributes[URL_PATH] ?? urlAttributes[URL_PATH], [HTTP_ROUTE]: parameterizedRoute, ...headerAttributes }); setCapturedScopesOnSpan(rootSpan, currentScope, isolationScope); } } else if (req instanceof Request) { spanName = `${req.method} ${parameterizedRoute}`; } else { spanName = `handler ${parameterizedRoute}`; } return startSpan( { name: spanName, op, attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "route", [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.function.nextjs.wrap_api_handler", [HTTP_ROUTE]: parameterizedRoute, ...urlAttributes, ...headerAttributes } }, () => { return handleCallbackErrors( () => wrappingTarget.apply(thisArg, args), (error) => { captureException(error, { mechanism: { type: "auto.function.nextjs.wrap_api_handler", handled: false } }); }, () => { waitUntil(flushSafelyWithTimeout()); } ); } ); }); } }); } export { wrapApiHandlerWithSentry }; //# sourceMappingURL=wrapApiHandlerWithSentry.js.map