Repository navigation
feat(nuxt, nitro): Serve the managed tunnel before the app's server middleware #25418
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
Merged
Merged
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
72edd0c
feat(nuxt, nitro): Serve the managed tunnel before the app's server m…
logaretm 4d8c86c
feat(nuxt, nitro): Serve the managed tunnel under the app's base URL
logaretm 6c4a1a1
fix(nitro): Drop the tunnel's dev server spans under `baseURL` too
logaretm fb959a5
fix(nuxt): Normalize the tunnel base path with the core util
logaretm e77d0ee
fix(nuxt, nitro): Serve the managed tunnel from `nitroApp.fetch` so r…
logaretm bffb551
fix(nuxt): Serve the Nitro v2 tunnel from the first h3 layer so route…
logaretm 9d55385
test(nitro): Check a client dropping the tunnel request isn't reporte…
logaretm 0f6271e
fix(nuxt): Serve the managed tunnel when the SDK is set up with sentr…
logaretm d543ed2
ref(nuxt, nitro): Report the base URL once with setManagedTunnelDefau…
logaretm 2460154
test(nuxt): Wait for the dev server before the tunnel tests
logaretm 867da3d
fix(nuxt): Don't add the tunnel plugin to a host without Nitro
logaretm 818f159
test(nuxt, nitro): Race the tunnel span with the shared helper, and d…
logaretm 8036b67
ref(nuxt): Let core normalize the base URL, and drop the tests that r…
logaretm a9dcd36
ref: Import the internal tunnel helpers under their `_INTERNAL_` names
logaretm f24e7e0
test: Stop checking the removed `X-Sentry-Tunnel` header
logaretm 259e744
test(nuxt, nitro): Serve the managed tunnel with `serveTunnelIntegrat…
logaretm File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 4 additions & 1 deletion
5
dev-packages/e2e-tests/test-applications/nitro-3/playwright.config.mjs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,10 @@ | ||
| import { getPlaywrightConfig } from '@sentry-internal/test-utils'; | ||
|
|
||
| const config = getPlaywrightConfig({ | ||
| startCommand: `pnpm start`, | ||
| startCommand: | ||
| process.env.TEST_ENV === 'development' | ||
| ? `PORT=3030 NODE_OPTIONS='--import ./instrument.mjs' pnpm exec vite dev --port 3030` | ||
| : `pnpm start`, | ||
| }); | ||
|
|
||
| export default config; |
7 changes: 6 additions & 1 deletion
7
dev-packages/e2e-tests/test-applications/nitro-3/server/middleware/test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 10 additions & 2 deletions
12
dev-packages/e2e-tests/test-applications/nitro-3/src/main.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,18 @@ | ||
| import * as Sentry from '@sentry/browser'; | ||
|
|
||
| declare const __E2E_TEST_TUNNEL__: boolean; | ||
| declare const __E2E_TEST_BASE_PATH__: string; | ||
|
|
||
| // Let's us test trace propagation | ||
| Sentry.init({ | ||
| environment: 'qa', | ||
| dsn: 'https://public@dsn.ingest.sentry.io/1337', | ||
| tunnel: 'http://localhost:3031/', // proxy server | ||
| dsn: __E2E_TEST_TUNNEL__ ? 'http://public@localhost:3031/1337' : 'https://public@dsn.ingest.sentry.io/1337', | ||
| // Plain Nitro has no client SDK to pass `baseURL` on, so the browser names it. The server picks it up itself. | ||
| tunnel: __E2E_TEST_TUNNEL__ | ||
| ? __E2E_TEST_BASE_PATH__ | ||
| ? { basePath: __E2E_TEST_BASE_PATH__ } | ||
| : true | ||
| : 'http://localhost:3031/', // proxy server | ||
| integrations: [Sentry.browserTracingIntegration()], | ||
| tracesSampleRate: 1.0, | ||
| }); |
70 changes: 70 additions & 0 deletions
70
dev-packages/e2e-tests/test-applications/nitro-3/tests/tunnel.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| import { expect, test } from '@playwright/test'; | ||
| import { | ||
| isServerSpanAt, | ||
| makeClientReportEnvelope, | ||
| waitForError, | ||
| watchForTunnelSpan, | ||
| } from '@sentry-internal/test-utils'; | ||
| import { getTunnelPath } from '@sentry/core'; | ||
| import { connect } from 'node:net'; | ||
|
|
||
| test.skip(!process.env.E2E_TEST_TUNNEL, 'Only runs in the tunnel variant'); | ||
|
|
||
| const BASE_PATH = process.env.E2E_TEST_BASE_PATH ?? ''; | ||
| const TUNNEL_PATH = new RegExp(`^${BASE_PATH}/[a-z0-9]{1,7}$`); | ||
|
|
||
| test('answers the managed tunnel before the app auth middleware', async ({ page }) => { | ||
| // The variant's auth middleware rejects every other POST. | ||
| expect((await page.request.post(`${BASE_PATH}/api/anything`, { data: 'x' })).status()).toBe(401); | ||
|
|
||
| const raceTunnelSpan = watchForTunnelSpan('nitro-3', isServerSpanAt(TUNNEL_PATH)); | ||
| const tunnelResponsePromise = page.waitForResponse( | ||
| response => response.request().method() === 'POST' && TUNNEL_PATH.test(new URL(response.url()).pathname), | ||
| ); | ||
|
|
||
| await page.goto(`${BASE_PATH}/`); | ||
|
|
||
| expect((await tunnelResponsePromise).status()).toBe(200); | ||
| expect( | ||
| await raceTunnelSpan(isServerSpanAt(`${BASE_PATH}/api/test-transaction`), () => | ||
| page.request.get(`${BASE_PATH}/api/test-transaction`), | ||
| ), | ||
| ).toBe('anchor'); | ||
| }); | ||
|
|
||
| test('answers a request to the managed tunnel itself', async ({ request }) => { | ||
| const dsn = 'http://public@localhost:3031/1337'; | ||
| const response = await request.post(`${BASE_PATH}${getTunnelPath(dsn)}`, { | ||
| data: makeClientReportEnvelope(dsn), | ||
| headers: { 'Content-Type': 'application/x-sentry-envelope' }, | ||
| }); | ||
|
|
||
| expect(response.status()).toBe(200); | ||
| }); | ||
|
|
||
| test('does not report a client that drops the connection before the envelope header as an error', async ({ | ||
| request, | ||
| }) => { | ||
| const dsn = 'http://public@localhost:3031/1337'; | ||
| const firstErrorPromise = waitForError('nitro-3', () => true); | ||
|
|
||
| // Part of the envelope header line, without its newline, then the connection drops. | ||
| await new Promise<void>(resolve => { | ||
| const socket = connect(3030, 'localhost', () => { | ||
| socket.write( | ||
| `POST ${BASE_PATH}${getTunnelPath(dsn)} HTTP/1.1\r\nHost: localhost:3030\r\nContent-Type: application/x-sentry-envelope\r\nContent-Length: 1000000\r\n\r\n`, | ||
| ); | ||
| socket.write(JSON.stringify({ dsn, padding: 'x'.repeat(1000) }).slice(0, 500)); | ||
| setTimeout(() => { | ||
| socket.destroy(); | ||
| resolve(); | ||
| }, 300); | ||
| }); | ||
| }); | ||
|
|
||
| // Errors are sent in order, so one from the dropped request would arrive before this one. | ||
| await request.get(`${BASE_PATH}/api/test-error`); | ||
|
|
||
| const firstError = await firstErrorPromise; | ||
| expect(firstError.exception?.values?.[0]?.value).toBe('This is a test error'); | ||
| }); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 4 additions & 0 deletions
4
dev-packages/e2e-tests/test-applications/nuxt-4-cloudflare/server/api/anchor.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| import { defineEventHandler } from '#imports'; | ||
|
|
||
| // A plain route for tests to request after the tunnel traffic. | ||
| export default defineEventHandler(() => 'ok'); |
7 changes: 6 additions & 1 deletion
7
dev-packages/e2e-tests/test-applications/nuxt-4-cloudflare/server/plugins/sentry.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,15 @@ | ||
| import { defineNitroPlugin } from '#imports'; | ||
| import { serveTunnelIntegration } from '@sentry/cloudflare'; | ||
| import { sentryCloudflareNitroPlugin } from '@sentry/nuxt/module/plugins'; | ||
|
|
||
| declare const __E2E_TEST_TUNNEL__: boolean; | ||
|
|
||
| export default defineNitroPlugin( | ||
| sentryCloudflareNitroPlugin({ | ||
| dsn: 'https://public@dsn.ingest.sentry.io/1337', | ||
| // The tunnel forwards to the DSN host, which is the event proxy in the tunnel variant. | ||
| dsn: __E2E_TEST_TUNNEL__ ? 'http://public@localhost:3031/1337' : 'https://public@dsn.ingest.sentry.io/1337', | ||
| tracesSampleRate: 1.0, | ||
| tunnel: 'http://localhost:3031/', // proxy server | ||
| integrations: __E2E_TEST_TUNNEL__ ? [serveTunnelIntegration()] : [], | ||
| }), | ||
| ); |
21 changes: 21 additions & 0 deletions
21
dev-packages/e2e-tests/test-applications/nuxt-4-cloudflare/tests/tunnel.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| import { expect, test } from '@playwright/test'; | ||
| import { isServerSpanAt, makeClientReportEnvelope, watchForTunnelSpan } from '@sentry-internal/test-utils'; | ||
|
|
||
| test.skip(!process.env.E2E_TEST_TUNNEL, 'Only runs in the tunnel variant'); | ||
|
|
||
| // The isolate's first tunnel request is the one a late span filter would let through, so this stays the only test. | ||
| test('answers the managed tunnel set up by `sentryCloudflareNitroPlugin`, without a span of it', async ({ | ||
| request, | ||
| }) => { | ||
| const dsn = 'http://public@localhost:3031/1337'; | ||
| const raceTunnelSpan = watchForTunnelSpan('nuxt-4-cloudflare', isServerSpanAt(/^\/app\/qpo967/)); | ||
|
|
||
| // The path the SDK derives from `dsn`. | ||
| const response = await request.post('/app/qpo967', { | ||
| data: makeClientReportEnvelope(dsn), | ||
| headers: { 'Content-Type': 'application/x-sentry-envelope' }, | ||
| }); | ||
|
|
||
| expect(response.status()).toBe(200); | ||
| expect(await raceTunnelSpan(isServerSpanAt('/app/api/anchor'), () => request.get('/app/api/anchor'))).toBe('anchor'); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 5 additions & 2 deletions
7
dev-packages/e2e-tests/test-applications/nuxt-4/sentry.server.config.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,15 @@ | ||
| import * as Sentry from '@sentry/nuxt'; | ||
|
|
||
| Sentry.init({ | ||
| dsn: 'https://public@dsn.ingest.sentry.io/1337', | ||
| dsn: process.env.E2E_TEST_TUNNEL ? 'http://public@localhost:3031/1337' : 'https://public@dsn.ingest.sentry.io/1337', | ||
| tracesSampleRate: 1.0, // Capture 100% of the transactions | ||
| tunnel: 'http://localhost:3031/', // proxy server | ||
| // Opt into the Sentry OpenTelemetry tracer provider in the "(tracer provider)" e2e variant. | ||
| // Leaving it `undefined` otherwise keeps the SDK's default (no provider). | ||
| enableOpenTelemetrySetup: process.env.E2E_TEST_OTEL_SETUP === 'true' ? true : undefined, | ||
| // Several tests trigger the same server error one after another, which Dedupe would drop. | ||
| integrations: integrations => integrations.filter(integration => integration.name !== 'Dedupe'), | ||
| integrations: integrations => [ | ||
| ...integrations.filter(integration => integration.name !== 'Dedupe'), | ||
| ...(process.env.E2E_TEST_TUNNEL ? [Sentry.serveTunnelIntegration()] : []), | ||
| ], | ||
| }); |
7 changes: 6 additions & 1 deletion
7
dev-packages/e2e-tests/test-applications/nuxt-4/server/middleware/03.auth.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.