diff --git a/packages/nextjs/src/common/wrapRouteHandlerWithSentry.ts b/packages/nextjs/src/common/wrapRouteHandlerWithSentry.ts index 06e969a737ce..1dadd72e3f43 100644 --- a/packages/nextjs/src/common/wrapRouteHandlerWithSentry.ts +++ b/packages/nextjs/src/common/wrapRouteHandlerWithSentry.ts @@ -8,6 +8,7 @@ import { getRootSpan, handleCallbackErrors, setHttpStatus, + spanToJSON, startSpan, } from '@sentry/core'; import type { Span } from '@sentry/types'; @@ -24,32 +25,41 @@ function startOrUpdateSpan(spanName: string, cb: (rootSpan: Span) => Promise { - return cb(span); + attributes, }, + cb, ); } + + // If `op` is set, we assume this was already processed before + // Probably this is a nested call, no need to update anything anymore + // OR, if we don't have next.span_type, we don't know where this comes from and don't want to mess with it + const existingAttributes = spanToJSON(rootSpan).data || {}; + if (existingAttributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] || !existingAttributes['next.span_type']) { + return cb(rootSpan); + } + + // Finally, we want to update the root span, as the ones generated by next are often not good enough for us + rootSpan.updateName(spanName); + rootSpan.setAttributes(attributes); + + return cb(rootSpan); } /**