diff --git a/packages/nuxt/src/server/sdk.ts b/packages/nuxt/src/server/sdk.ts index 6c4dd4712a1a..eab3e4b1a8a0 100644 --- a/packages/nuxt/src/server/sdk.ts +++ b/packages/nuxt/src/server/sdk.ts @@ -1,3 +1,4 @@ +import * as path from 'node:path'; import { applySdkMetadata, flush, getGlobalScope } from '@sentry/core'; import { logger, vercelWaitUntil } from '@sentry/core'; import { @@ -33,23 +34,26 @@ export function init(options: SentryNuxtServerOptions): Client | undefined { } /** - * Filter out transactions for Nuxt build assets - * This regex matches the default path to the nuxt-generated build assets (`_nuxt`). + * Filter out transactions for resource requests which we don't want to send to Sentry + * for quota reasons. * * Only exported for testing */ export function lowQualityTransactionsFilter(options: SentryNuxtServerOptions): EventProcessor { return Object.assign( (event => { - if (event.type === 'transaction' && event.transaction?.match(/^GET \/_nuxt\//)) { - // todo: the buildAssetDir could be changed in the nuxt config - change this to a more generic solution + if (event.type !== 'transaction' || !event.transaction) { + return event; + } + // We don't want to send transaction for file requests, so everything ending with a *.someExtension should be filtered out + // path.extname will return an empty string for normal page requests + if (path.extname(event.transaction)) { options.debug && DEBUG_BUILD && logger.log('NuxtLowQualityTransactionsFilter filtered transaction: ', event.transaction); return null; - } else { - return event; } + return event; }) satisfies EventProcessor, { id: 'NuxtLowQualityTransactionsFilter' }, ); diff --git a/packages/nuxt/test/server/sdk.test.ts b/packages/nuxt/test/server/sdk.test.ts index 56888afc9a79..611c24e1dcf4 100644 --- a/packages/nuxt/test/server/sdk.test.ts +++ b/packages/nuxt/test/server/sdk.test.ts @@ -45,45 +45,39 @@ describe('Nuxt Server SDK', () => { expect(init({})).not.toBeUndefined(); }); - it('filters out low quality transactions', async () => { + describe('low quality transactions filter (%s)', () => { const beforeSendEvent = vi.fn(event => event); const client = init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', }) as NodeClient; client.on('beforeSendEvent', beforeSendEvent); - client.captureEvent({ type: 'transaction', transaction: 'GET /' }); - client.captureEvent({ type: 'transaction', transaction: 'GET /_nuxt/some_asset.js' }); - // Although this has the name of the build asset directory (_nuxt), it should not be filtered out as it would not match the regex - client.captureEvent({ type: 'transaction', transaction: 'GET _nuxt/some_asset.js' }); - client.captureEvent({ type: 'transaction', transaction: 'POST /_server' }); - - await client!.flush(); + it.each([ + [ + 'GET /_nuxt/some_asset.js', + 'GET _nuxt/some_asset.js', + 'GET /icons/favicon.ico', + 'GET /assets/logo.png', + 'GET /icons/zones/forest.svg', + ], + ])('filters out low quality transactions', async transaction => { + client.captureEvent({ type: 'transaction', transaction }); + await client!.flush(); + expect(beforeSendEvent).not.toHaveBeenCalled(); + }); - expect(beforeSendEvent).toHaveBeenCalledTimes(3); - expect(beforeSendEvent).toHaveBeenCalledWith( - expect.objectContaining({ - transaction: 'GET /', - }), - expect.any(Object), - ); - expect(beforeSendEvent).toHaveBeenCalledWith( - expect.objectContaining({ - transaction: 'GET _nuxt/some_asset.js', - }), - expect.any(Object), - ); - expect(beforeSendEvent).not.toHaveBeenCalledWith( - expect.objectContaining({ - transaction: 'GET /_nuxt/some_asset.js', - }), - expect.any(Object), - ); - expect(beforeSendEvent).toHaveBeenCalledWith( - expect.objectContaining({ - transaction: 'POST /_server', - }), - expect.any(Object), + it.each(['GET /', 'POST /_server'])( + 'does not filter out high quality or route transactions (%s)', + async transaction => { + client.captureEvent({ type: 'transaction', transaction }); + await client!.flush(); + expect(beforeSendEvent).toHaveBeenCalledWith( + expect.objectContaining({ + transaction, + }), + expect.any(Object), + ); + }, ); });