Repository navigation
Conversation
size-limit report 📦Compared: bb7f6bf (PR test merge using develop at 8d098a1) Against: dd9903c (develop) · base run #64617
|
|
bugbot run |
0bd8edd to
a0d5655
Compare
|
bugbot run |
a0d5655 to
bff33ce
Compare
|
bugbot run |
bff33ce to
61392db
Compare
|
bugbot run |
5472088 to
ae51678
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 5472088. Configure here.
| basePath: userNextConfig.basePath ?? '', | ||
| ...(path && { path }), | ||
| ...(allowedDsns && { allowedDsns }), | ||
| }; |
There was a problem hiding this comment.
Tunnel ignores Next.js trailingSlash
Medium Severity
getManagedTunnelOptions copies basePath from the Next.js config but not trailingSlash, so the browser posts to the slashless DSN path. With trailingSlash: true, Next.js 308s that POST before beforeFiles rewrites, and the DSN rewrite source also omits the optional trailing slash that the fixed-path rewrite includes. Unload-time keepalive fetches often will not follow that redirect, so events never reach the tunnel.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 5472088. Configure here.
ae51678 to
9c50125
Compare
9c50125 to
e94f25d
Compare
e94f25d to
efc9b07
Compare
efc9b07 to
2e8e2b3
Compare
2e8e2b3 to
2c6c3d8
Compare
…om the DSN (#25199) ### Overview SDK Tunnel is a feature that allows client SDKs (e.g: browser) to send their requests through an endpoint that lives on the user's own application that forwards to Sentry. This bypasses adblockers and similar extensions. Tunnels could be configured as a fixed endpoint defined by the user (defaulted to `/monitoring`) but that usually ends up in global adblocker lists. Alternatively, users can tell the SDK to use a random endpoint to bypass that. Previously the tunnel logic mostly lived in client bundles and in server frameworks build time, this had two issues: - Both client and server bundles needed to share a single ENV during build, or a single process. So both can agree on the random URL generated. - CI/CD workflows means assets can drift, so older client bundles might be sending requests to older server bundles and vice versa, what happens then is during the rollout/phase-out, the random endpoints won't match and thus these envelopes will be getting 404'ed. This stack of PRs re-works the idea by moving to more stable yet random URL generation based on the client's DSN and moves the tunnel handling into the runtime of the core SDK. Meaning tunneling now is a core SDK capability rather than a meta framework feature. Here is how it looks for users: ```ts // client, posts to a path hashed from the DSN, e.g. `/k3x9q2a` Sentry.init({ dsn, tunnel: true }); // server, nothing to do in a meta-framework, the SDK answers that path from its request hook. // You only need this if the browser uses a different DSN than the server. Sentry.init({ dsn, tunnel: { allowedDsns: [browserDsn] } }); ``` And a tunneled request goes like this: the framework hook calls `handleTunnelRequestIfMatched`, if the path matches it checks the envelope's DSN against the allowed ones and forwards it to Sentry, otherwise the request continues as normal. ### This PR This sets up the core for the new tunnel mechanism that the rest of the stack will be implemented against, it does the following: - Sets up the tunnel generation and matching logic. - Sets up global span/breadcrumb ignore rules for tunneled requests. - Adds request checking, header forwarding, and the proxying to the Sentry SaaS DSN. It also sets up a couple of key decisions that will carry over throughout the stack: - **Base paths are respected always:** if a user sets `/app` as a base path our tunnels handlers will expect that prefix. - **Servers always allow their own DSNs:** This avoids the footgun where a user misconfigures `allowedDSNs` on the server, this correction only applies if the client and server share the same DSN, if there is a different DSN involved then it is on the user to configure that correctly. Will work on documenting this. ### Reviewing the stack This PR and #25200 are where the actual behavior lives so these need the closest look, mainly `forwardEnvelope` and the base path handling in `tunnel.ts`. The framework PRs all follow the same pattern: find the earliest request hook the framework gives us, call the core handler there, and pass the framework's base path along. They are small, so ideally whoever knows that framework best picks it up: - TanStack Start #25408 - SvelteKit #25415 - Nuxt and Nitro #25418, this one has more going on since it has to run before the user's own server middleware - Astro #25419 - Remix #25420 - React Router #25422 - SolidStart #25423 #25414 is tests only, and Next.js #25424 is on hold, I will split it up before it's ready.
5bc562c to
ef27f39
Compare
Optional E2E testsAll optional checks were successful. 10 successful. See the run. Successful checks
|
|
One or more gzipped bundles increased by more than 500 bytes. If this increase is intentional, add the Accept Bundlesize Increase label to this PR to rerun and accept the check. |
…equest` The tunnel route handler now leaves DSN normalization, the allowlist and tracing suppression to core. As in every other SDK, `allowedDsns` adds to the server's own DSN, and the default `POST` accepts the DSNs `serveTunnelIntegration` allows.
…ePath` `tunnel: true` in the browser now sends to `<basePath>/<hash>`, like the SvelteKit and React Router SDKs do with their base paths. A `basePath` the user set and a `tunnel` URL stay as written.
…the server `withSentryConfig` now injects `basePath` into production server and edge builds, not only in dev, and the server, edge and Cloudflare inits pass it to `setManagedTunnelDefaults`. `serveTunnelIntegration` then matches `/<basePath>/<hash>`, like the browser sends.
Vercel serves unknown paths from its CDN without running the app, so the runtime never sees managed tunnel requests there. On Vercel builds without `tunnelRoute`, `withSentryConfig` writes the tunnel route handler and rewrites envelope requests to the DSN-derived paths there. The handler answers only when `serveTunnelIntegration` is set up, and on a cold start too. Pages Router apps get an `app` directory with only this route.
`tunnel: true` in the browser and `serveTunnelIntegration` on the server serve the tunnel on every Next.js deployment, so `tunnelRoute` and the `@sentry/nextjs/tunnel` route handlers are deprecated. `withSentryConfig` warns when `tunnelRoute` is set.


This overhauls the tunnel implementation of Next.js by doing a few things:
omitfor the transport options.The way it works varies depeding on how the user deploys their application.
On Conventional Servers/Platforms
Our runtime patchers introduced in this stack handle the tunnel request, the user's Next.js app never handles any of these.
On Vercel
We utilize the two-hop idea we did in #25456 by writing a small idempotent app router file. The re-write rules move traffic to the new handler, and the file exports a
POSThandler for the route.Vercel applies certain rules and responds with 404 for tunnel requests that aren't present in re-writes or app router, so our runtime patchers will never trigger. Which is why this workaround was needed.
For everyone else, the runtime patchers will work.