diff --git a/packages/nextjs/src/common/pages-router-instrumentation/wrapApiHandlerWithSentry.ts b/packages/nextjs/src/common/pages-router-instrumentation/wrapApiHandlerWithSentry.ts index 51afa404c113..c9a1446b50ee 100644 --- a/packages/nextjs/src/common/pages-router-instrumentation/wrapApiHandlerWithSentry.ts +++ b/packages/nextjs/src/common/pages-router-instrumentation/wrapApiHandlerWithSentry.ts @@ -2,6 +2,8 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, captureException, continueTrace, + getActiveSpan, + getRootSpan, setHttpStatus, startSpanManual, withIsolationScope, @@ -9,6 +11,7 @@ import { import { consoleSandbox, isString, logger, objectify } from '@sentry/utils'; import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core'; +import { TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION } from '../span-attributes-with-logic-attached'; import type { AugmentedNextApiRequest, AugmentedNextApiResponse, NextApiHandler } from '../types'; import { flushSafelyWithTimeout } from '../utils/responseEnd'; import { escapeNextjsTracing } from '../utils/tracingUtils'; @@ -24,6 +27,15 @@ import { vercelWaitUntil } from '../utils/vercelWaitUntil'; * @returns The wrapped handler */ export function wrapApiHandlerWithSentry(apiHandler: NextApiHandler, parameterizedRoute: string): NextApiHandler { + // Since the API route handler spans emitted by Next.js are super buggy with completely wrong timestamps + // (fix pending at the time of writing this: https://github.com/vercel/next.js/pull/70908) we want to intentionally + // drop them. In the future, when Next.js' OTEL instrumentation is in a high-quality place we can potentially think + // about keeping them. + const nextJsOwnedSpan = getActiveSpan(); + if (nextJsOwnedSpan) { + getRootSpan(nextJsOwnedSpan)?.setAttribute(TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION, true); + } + return new Proxy(apiHandler, { apply: ( wrappingTarget, diff --git a/packages/nextjs/src/common/span-attributes-with-logic-attached.ts b/packages/nextjs/src/common/span-attributes-with-logic-attached.ts new file mode 100644 index 000000000000..f6b5b46fdcac --- /dev/null +++ b/packages/nextjs/src/common/span-attributes-with-logic-attached.ts @@ -0,0 +1,4 @@ +/** + * If this attribute is attached to a transaction, the Next.js SDK will drop that transaction. + */ +export const TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION = 'sentry.drop_transaction'; diff --git a/packages/nextjs/src/server/index.ts b/packages/nextjs/src/server/index.ts index 1bfc57b44418..5ac96c0eac77 100644 --- a/packages/nextjs/src/server/index.ts +++ b/packages/nextjs/src/server/index.ts @@ -21,6 +21,7 @@ import type { EventProcessor } from '@sentry/types'; import { DEBUG_BUILD } from '../common/debug-build'; import { devErrorSymbolicationEventProcessor } from '../common/devErrorSymbolicationEventProcessor'; import { getVercelEnv } from '../common/getVercelEnv'; +import { TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION } from '../common/span-attributes-with-logic-attached'; import { isBuild } from '../common/utils/isBuild'; import { distDirRewriteFramesIntegration } from './distDirRewriteFramesIntegration'; @@ -244,6 +245,11 @@ export function init(options: NodeOptions): NodeClient | undefined { return null; } + // Filter transactions that we explicitly want to drop. + if (event.contexts?.trace?.data?.[TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION]) { + return null; + } + return event; } else { return event;