-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
feat(nextjs): remove tracing from pages router API routes #18394
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
feat(nextjs): remove tracing from pages router API routes #18394
Conversation
2af20e5 to
2516846
Compare
node-overhead report 🧳Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.
|
9cf8b89 to
27e02e0
Compare
c055f2d to
8102dd9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR removes explicit tracing instrumentation from Pages Router API route wrappers (wrapApiHandlerWithSentry) for both Node.js server and Edge runtimes, relying instead on Next.js's built-in OpenTelemetry instrumentation to create transaction spans. The wrappers now only handle error capture, transaction name setting on isolation scope, and route backfilling.
Key Changes:
- Removed manual span creation (
startSpanManual,startSpan) from API route wrappers - Wrappers now set transaction names on isolation scope and use route backfill attributes for parameterized route names
- Updated test expectations to reflect origin change from
'auto.http.nextjs'to'auto'(from Next.js OTEL) - Added comprehensive Next.js 16 Pages Router test application with 36+ test cases
Reviewed changes
Copilot reviewed 74 out of 76 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
packages/nextjs/src/common/pages-router-instrumentation/wrapApiHandlerWithSentry.ts |
Removed tracing logic; now only captures errors and sets transaction metadata via isolation scope and route backfill |
packages/nextjs/src/edge/wrapApiHandlerWithSentry.ts |
Removed tracing logic from edge runtime wrapper; simplified to error monitoring only |
packages/nextjs/src/server/index.ts |
Added SEMANTIC_ATTRIBUTE_SENTRY_SOURCE to route backfill logic to ensure proper transaction source attribution |
packages/nextjs/test/config/withSentry.test.ts |
Deleted unit test that verified explicit span creation (no longer applicable) |
dev-packages/e2e-tests/test-applications/nextjs-13/tests/**/*.test.ts |
Updated assertions to expect 'auto' origin instead of 'auto.http.nextjs' |
dev-packages/e2e-tests/test-applications/create-next-app/tests/**/*.test.ts |
Updated assertions for new tracing behavior with flexible parent span matching |
dev-packages/e2e-tests/test-applications/nextjs-pages-dir/tests/edge-route.test.ts |
Removed runtime context assertions and skipped scope isolation test |
dev-packages/e2e-tests/test-applications/nextjs-16-pages-dir/**/* |
New comprehensive test application with 36 test cases for Next.js 16 Pages Router covering both webpack and turbopack |
dev-packages/e2e-tests/test-applications/nextjs-16-pages-dir/TEST_STATUS.md |
Detailed documentation of test status, known issues, and future work items |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
.../e2e-tests/test-applications/nextjs-16-pages-dir/tests/server/excluded-api-endpoints.test.ts
Show resolved
Hide resolved
.../e2e-tests/test-applications/nextjs-16-pages-dir/tests/server/excluded-api-endpoints.test.ts
Show resolved
Hide resolved
dev-packages/e2e-tests/test-applications/nextjs-16-pages-dir/tests/edge-route.test.ts
Show resolved
Hide resolved
dev-packages/e2e-tests/test-applications/nextjs-16-pages-dir/tests/pages-ssr-errors.test.ts
Show resolved
Hide resolved
dev-packages/e2e-tests/test-applications/nextjs-16-pages-dir/tests/proxy.test.ts
Show resolved
Hide resolved
dev-packages/e2e-tests/test-applications/nextjs-16-pages-dir/tests/transactions.test.ts
Show resolved
Hide resolved
...kages/e2e-tests/test-applications/nextjs-16-pages-dir/pages/pages-router/ssr-error-class.tsx
Show resolved
Hide resolved
...packages/e2e-tests/test-applications/nextjs-16-pages-dir/pages/pages-router/ssr-error-fc.tsx
Show resolved
Hide resolved
| // as the runtime freezes as soon as the error is thrown below | ||
| await flushSafelyWithTimeout(); | ||
|
|
||
| // We rethrow here so that nextjs can do with the error whatever it would normally do. (Sometimes "whatever it | ||
| // would normally do" is to allow the error to bubble up to the global handlers - another reason we need to mark | ||
| // the error as already having been captured.) | ||
| throw objectifiedErr; | ||
| } | ||
| }, | ||
| }); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: The removal of waitUntil(flushSafelyWithTimeout()) for successful requests in serverless environments will cause Sentry events to be lost, as the runtime can terminate before flushing is complete.
Severity: CRITICAL | Confidence: High
🔍 Detailed Analysis
For successful requests in both server and edge runtimes, Sentry events are no longer guaranteed to be flushed. The previous implementation used waitUntil(flushSafelyWithTimeout()) to ensure background event transmission completed in serverless environments (like Vercel or Cloudflare) without blocking the response. The new code removes this mechanism for the success path. As a result, the serverless runtime can terminate immediately after the request handler finishes, but before Sentry has finished sending the event, leading to data loss.
💡 Suggested Fix
Reinstate the non-blocking flush mechanism for successful requests. In the finally block of the wrapper, call waitUntil(flushSafelyWithTimeout()) to ensure events are sent without delaying the HTTP response. This was the behavior in the previous implementation and is critical for serverless platforms.
🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location:
packages/nextjs/src/common/pages-router-instrumentation/wrapApiHandlerWithSentry.ts#L49-L103
Potential issue: For successful requests in both server and edge runtimes, Sentry events
are no longer guaranteed to be flushed. The previous implementation used
`waitUntil(flushSafelyWithTimeout())` to ensure background event transmission completed
in serverless environments (like Vercel or Cloudflare) without blocking the response.
The new code removes this mechanism for the success path. As a result, the serverless
runtime can terminate immediately after the request handler finishes, but before Sentry
has finished sending the event, leading to data loss.
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 6728031
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I switched to a blocking await here before throwing which should work better than calling waitUntil then throwing as the runtime can shutdown as soon as an unhandled error like these are thrown.
This matches the logic we have in the other API handler wrapper.
This is a big PR because of the tests added, the logic changes themselves are pretty minimal, so make sure to filter out the files when reviewing.
Actual Changes
Removed traces from
wrapApiHandlerWithSentryfor both the server runtime and the edge runtimeTests Added
Since we are dropping explicit trace wrapping logic from the pages router templates, we needed to have tests on Next 16 to make sure the page router there still works in both Turbopack and Webpack with minimal differences in the quality of the traces.
We have around 36 test case to check, but only 20 can pass at this time due to the wrapping logic still present, ideally as we move towards removing templates entirely, we can then unskip those tests and tighten many of the assertions we have to accommodate for it.
I added TODOs and a
TEST_STATUS.mddocument to detail what we should update once the SDK drops more of the wrapping logic it currently has.Closes #18450 (added automatically)