Add a tunnel route helper for TanStack Start React#20264
Add a tunnel route helper for TanStack Start React#20264nikolovlazar wants to merge 7 commits intodevelopfrom
Conversation
Semver Impact of This PR⚪ None (no version bump detected) 📋 Changelog PreviewThis is how your changes will appear in the changelog. New Features ✨Cloudflare
Core
Deps
Other
Bug Fixes 🐛Deno
Other
Internal Changes 🔧Ci
Deps
Other
Other
🤖 This preview updates automatically when you update the PR. |
There was a problem hiding this comment.
Pull request overview
Adds a TanStack Start server-route helper in @sentry/tanstackstart-react to make setting up a Sentry tunnel endpoint a one-liner, with unit tests to validate the POST-only route shape and forwarding behavior.
Changes:
- Introduce
createSentryTunnelRoutewhich wraps@sentry/core’shandleTunnelRequestfor TanStack Start server routes. - Export the helper from the package’s server entrypoint.
- Add unit tests covering the POST-only handler shape and correct request/options forwarding.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| yarn.lock | Lockfile updates (not directly related to the new tunnel helper). |
| packages/tanstackstart-react/src/server/tunnelRoute.ts | Adds createSentryTunnelRoute helper wrapping the core tunnel handler. |
| packages/tanstackstart-react/src/server/index.ts | Re-exports createSentryTunnelRoute from the server entrypoint. |
| packages/tanstackstart-react/test/server/tunnelRoute.test.ts | Adds focused unit tests for handler shape and forwarding behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Missing integration or E2E test for new feature
- Added E2E test file (tunnel.test.ts) and tunnel route (api.tunnel.ts) to verify createSentryTunnelRoute functionality in the tanstackstart-react E2E test application.
Or push these changes by commenting:
@cursor push b1fe0b60b9
Preview (b1fe0b60b9)
diff --git a/dev-packages/e2e-tests/test-applications/tanstackstart-react/src/routes/api.tunnel.ts b/dev-packages/e2e-tests/test-applications/tanstackstart-react/src/routes/api.tunnel.ts
new file mode 100644
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/tanstackstart-react/src/routes/api.tunnel.ts
@@ -1,0 +1,8 @@
+import { createFileRoute } from '@tanstack/react-router';
+import { createSentryTunnelRoute } from '@sentry/tanstackstart-react';
+
+export const Route = createFileRoute('/api/tunnel')({
+ server: createSentryTunnelRoute({
+ allowedDsns: [process.env.E2E_TEST_DSN || ''],
+ }),
+});
diff --git a/dev-packages/e2e-tests/test-applications/tanstackstart-react/tests/tunnel.test.ts b/dev-packages/e2e-tests/test-applications/tanstackstart-react/tests/tunnel.test.ts
new file mode 100644
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/tanstackstart-react/tests/tunnel.test.ts
@@ -1,0 +1,66 @@
+import { expect, test } from '@playwright/test';
+import { waitForError } from '@sentry-internal/test-utils';
+
+test('Tunnel route forwards envelopes to Sentry', async ({ baseURL }) => {
+ const errorEventPromise = waitForError('tanstackstart-react', errorEvent => {
+ return errorEvent?.exception?.values?.[0]?.value === 'Test error for tunnel route';
+ });
+
+ const dsn = process.env.E2E_TEST_DSN || '';
+ const [protocol, rest] = dsn.split('://');
+ const [auth, hostAndPath] = rest.split('@');
+ const [publicKey] = auth.split(':');
+ const [host, ...pathParts] = hostAndPath.split('/');
+ const projectId = pathParts[pathParts.length - 1];
+
+ const envelope = [
+ JSON.stringify({ event_id: crypto.randomUUID(), sent_at: new Date().toISOString() }),
+ JSON.stringify({
+ type: 'event',
+ length: 0,
+ }),
+ JSON.stringify({
+ exception: {
+ values: [
+ {
+ type: 'Error',
+ value: 'Test error for tunnel route',
+ },
+ ],
+ },
+ platform: 'javascript',
+ sdk: {
+ name: 'sentry.javascript.tanstackstart-react',
+ version: '0.0.0',
+ },
+ timestamp: Date.now() / 1000,
+ }),
+ ].join('\n');
+
+ const tunnelUrl = `${baseURL}/api/tunnel`;
+ const sentryUrl = `${protocol}://${host}/api/${projectId}/envelope/`;
+
+ const response = await fetch(tunnelUrl, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/x-sentry-envelope',
+ 'X-Sentry-Auth': `Sentry sentry_key=${publicKey}, sentry_version=7`,
+ },
+ body: `${sentryUrl}\n${envelope}`,
+ });
+
+ expect(response.status).toBe(200);
+
+ const errorEvent = await errorEventPromise;
+
+ expect(errorEvent).toMatchObject({
+ exception: {
+ values: [
+ {
+ type: 'Error',
+ value: 'Test error for tunnel route',
+ },
+ ],
+ },
+ });
+});This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.
size-limit report 📦
|
logaretm
left a comment
There was a problem hiding this comment.
I think it is worth adding an e2e test case for this in one of the tanstack test applications we have.
It will also act as a live way to show how to set it up in an application, I think dev-packages/e2e-tests/test-applications/tanstackstart-react can be a good place for it or maybe a new application if you come across conflicts with pre-existing tests.
yes I did try that, but I needed to rip out the local tunnel that was defined at this file. In order not to risk breaking existing testing functionality, I didn't push the code. Should I create a different tanstack start app instead, @logaretm? |
|
@nikolovlazar Yep that works, or if you feel extra fancy check my comment here. |
…github.com:getsentry/sentry-javascript into lazarnikolov/js-2140-tanstack-start-tunnel-adapter
| if (process.env[MANAGED_TUNNEL_ROUTE_PATH_ENV_KEY]) { | ||
| return process.env[MANAGED_TUNNEL_ROUTE_PATH_ENV_KEY]; | ||
| } |
There was a problem hiding this comment.
Bug: The tunnel route path read from the __SENTRY_TANSTACKSTART_TUNNEL_ROUTE__ environment variable is returned without validation, bypassing checks for invalid characters.
Severity: LOW
Suggested Fix
Validate the path retrieved from the process.env[MANAGED_TUNNEL_ROUTE_PATH_ENV_KEY] environment variable before returning it. The validation should be the same as the one applied to user-provided string paths in validateTunnelRouteOptions.
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/tanstackstart-react/src/vite/tunnelRoute.ts#L42-L44
Potential issue: The function `resolveTunnelRoute` checks for the
`__SENTRY_TANSTACKSTART_TUNNEL_ROUTE__` environment variable and, if it's set, returns
its value directly. This bypasses the validation logic in `validateTunnelRouteOptions`
that checks for invalid characters like `?` or `#`. If this internal environment
variable is polluted by an external source (e.g., in a CI environment) with an invalid
path, that invalid path will be injected into the client bundle, potentially breaking
the Sentry tunneling functionality.
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 98202a9. Configure here.
| const responseUrl = new URL(response.url()); | ||
|
|
||
| return responseUrl.origin === pageOrigin && response.request().method() === 'POST'; | ||
| }); |
There was a problem hiding this comment.
Overly broad POST matcher risks test flakiness
Low Severity
The page.waitForResponse filter matches any POST request to the same origin, not specifically the tunnel endpoint. Other same-origin POST requests (e.g., pageload transaction envelopes, server function calls) could satisfy the matcher first, causing the test to assert against the wrong response. Narrowing the filter (e.g., matching on the expected tunnel pathname) would make it more robust.
Triggered by project rule: PR Review Guidelines for Cursor Bot
Reviewed by Cursor Bugbot for commit 98202a9. Configure here.



Summary
createSentryTunnelRouteto@sentry/tanstackstart-reactas a one-line server route adapter around the core tunnel handlersentryTanstackStart()(the existing Vite integration) with a newtunnelRouteoption which can automatically register a same-origin tunnel route and set the clienttunneloption to point to ittunnelRoutevariants:tunnel: true, default): generates an opaque route path once per dev session / production build so ad blockers can’t reliably target it by a known pathtunnel: '/custom-path'): uses an explicit fixed tunnel route pathNotes
yarn.lockcontains unrelated changes and should be reviewed separatelyTesting
cd packages/tanstackstart-react && yarn test/monitorreturns200and forwards envelopes to a real Sentry project. I also made sure session replays are being handled correctly. Screenshots from my Sentry org's usage indicating the events were received:Examples
createSentryTunnelRoute(manual server route)