From 56c4346668c474338321eb9d7c47a724f1d85f7d Mon Sep 17 00:00:00 2001 From: RulaKhaled Date: Wed, 7 May 2025 13:32:49 +0200 Subject: [PATCH 1/7] feat(react-router): Create a transaction filter for react router --- packages/react-router/src/server/sdk.ts | 30 ++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/react-router/src/server/sdk.ts b/packages/react-router/src/server/sdk.ts index d1e6b32b1d96..0f87fa40a102 100644 --- a/packages/react-router/src/server/sdk.ts +++ b/packages/react-router/src/server/sdk.ts @@ -1,4 +1,4 @@ -import { applySdkMetadata, logger, setTag } from '@sentry/core'; +import { type EventProcessor, applySdkMetadata, getGlobalScope, logger, setTag } from '@sentry/core'; import type { NodeClient, NodeOptions } from '@sentry/node'; import { init as initNodeSdk } from '@sentry/node'; import { DEBUG_BUILD } from '../common/debug-build'; @@ -20,5 +20,33 @@ export function init(options: NodeOptions): NodeClient | undefined { setTag('runtime', 'node'); DEBUG_BUILD && logger.log('SDK successfully initialized'); + + getGlobalScope().addEventProcessor(lowQualityTransactionsFilter(options)); + return client; } + +/** + * Filters out noisy transactions such as requests to node_modules + * + * @param options The NodeOptions passed to the SDK + * @returns An EventProcessor that filters low-quality transactions + */ +export function lowQualityTransactionsFilter(options: NodeOptions): EventProcessor { + return Object.assign( + (event => { + if (event.type !== 'transaction' || !event.transaction) { + return event; + } + + if (event.transaction.match(/\/node_modules\//)) { + options.debug && + logger.log('[ReactRouter] Filtered node_modules transaction:', event.transaction); + return null; + } + + return event; + }) satisfies EventProcessor, + { id: 'ReactRouterLowQualityTransactionsFilter' }, + ); +} From 354066608b21f1ab0a7543689786629a6ba11f10 Mon Sep 17 00:00:00 2001 From: RulaKhaled Date: Wed, 7 May 2025 14:55:04 +0200 Subject: [PATCH 2/7] Update react router sdk tests --- packages/react-router/src/server/sdk.ts | 11 +- packages/react-router/test/server/sdk.test.ts | 110 +++++++++++++++++- 2 files changed, 116 insertions(+), 5 deletions(-) diff --git a/packages/react-router/src/server/sdk.ts b/packages/react-router/src/server/sdk.ts index 0f87fa40a102..1380f9af3235 100644 --- a/packages/react-router/src/server/sdk.ts +++ b/packages/react-router/src/server/sdk.ts @@ -26,8 +26,14 @@ export function init(options: NodeOptions): NodeClient | undefined { return client; } +const matchedRegexes = [ + /GET \/node_modules\//, + /GET \/favicon\.ico/, + /GET \/@id\//, +]; + /** - * Filters out noisy transactions such as requests to node_modules + * Filters out noisy transactions such as requests to node_modules, favicon.ico, @id/ * * @param options The NodeOptions passed to the SDK * @returns An EventProcessor that filters low-quality transactions @@ -35,11 +41,12 @@ export function init(options: NodeOptions): NodeClient | undefined { export function lowQualityTransactionsFilter(options: NodeOptions): EventProcessor { return Object.assign( (event => { + if (event.type !== 'transaction' || !event.transaction) { return event; } - if (event.transaction.match(/\/node_modules\//)) { + if (matchedRegexes.some(regex => event.transaction?.match(regex))) { options.debug && logger.log('[ReactRouter] Filtered node_modules transaction:', event.transaction); return null; diff --git a/packages/react-router/test/server/sdk.test.ts b/packages/react-router/test/server/sdk.test.ts index 55c12935fe66..cb4423b5e2c0 100644 --- a/packages/react-router/test/server/sdk.test.ts +++ b/packages/react-router/test/server/sdk.test.ts @@ -1,7 +1,12 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; + +import { getGlobalScope } from '@sentry/core'; +import type { Event, EventType } from '@sentry/core'; import * as SentryNode from '@sentry/node'; +import type { NodeClient } from '@sentry/node'; import { SDK_VERSION } from '@sentry/node'; -import { afterEach, describe, expect, it, vi } from 'vitest'; -import { init as reactRouterInit } from '../../src/server/sdk'; + +import { init as reactRouterInit, lowQualityTransactionsFilter } from '../../src/server/sdk'; const nodeInit = vi.spyOn(SentryNode, 'init'); @@ -39,7 +44,106 @@ describe('React Router server SDK', () => { }); it('returns client from init', () => { - expect(reactRouterInit({})).not.toBeUndefined(); + const client = reactRouterInit({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + }) as NodeClient; + expect(client).not.toBeUndefined(); + }); + + it('registers the low quality transactions filter', async () => { + const addEventProcessor = vi.spyOn(getGlobalScope(), 'addEventProcessor'); + addEventProcessor.mockClear(); + + reactRouterInit({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + }) as NodeClient; + + expect(addEventProcessor).toHaveBeenCalledTimes(1); + const processor = addEventProcessor.mock.calls[0]![0]; + expect(processor?.id).toEqual('ReactRouterLowQualityTransactionsFilter'); + }); + + describe('transaction filtering', () => { + const beforeSendEvent = vi.fn(event => event); + let client: NodeClient; + + beforeEach(() => { + vi.clearAllMocks(); + beforeSendEvent.mockClear(); + SentryNode.getGlobalScope().clear(); + + client = reactRouterInit({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + }) as NodeClient; + + client.on('beforeSendEvent', beforeSendEvent); + }); + + describe('filters out low quality transactions', () => { + it.each([ + 'GET /node_modules/react/index.js', + 'GET /favicon.ico', + 'GET /@id/package', + ])('%s', async (transaction) => { + client.captureEvent({ type: 'transaction', transaction }); + + await client.flush(); + + expect(beforeSendEvent).not.toHaveBeenCalled(); + }); + }); + + describe('allows high quality transactions', () => { + it.each([ + 'GET /', + 'GET /users', + 'POST /api/data', + 'GET /projects/123', + ])('%s', async (transaction) => { + client.captureEvent({ type: 'transaction', transaction }); + + await client.flush(); + + expect(beforeSendEvent).toHaveBeenCalledWith( + expect.objectContaining({ transaction }), + expect.any(Object) + ); + }); + }); + }); + }); + + describe('lowQualityTransactionsFilter', () => { + describe('filters out low quality transactions', () => { + it.each([ + ['node_modules request', 'GET /node_modules/react/index.js'], + ['favicon.ico request', 'GET /favicon.ico'], + ['@id request', 'GET /@id/package'] + ])('%s', (description, transaction) => { + const filter = lowQualityTransactionsFilter({}); + const event = { + type: 'transaction' as EventType, + transaction, + } as Event; + + expect(filter(event, {})).toBeNull(); + }); + }); + + describe('does not filter good transactions', () => { + it.each([ + ['normal page request', 'GET /users'], + ['API request', 'POST /api/users'], + ['app route', 'GET /projects/123'] + ])('%s', (description, transaction) => { + const filter = lowQualityTransactionsFilter({}); + const event = { + type: 'transaction' as EventType, + transaction, + } as Event; + + expect(filter(event, {})).toBe(event); + }); }); }); }); From aa9e709d2fdd82e2a83a7b7010e03ed58de26f39 Mon Sep 17 00:00:00 2001 From: RulaKhaled Date: Wed, 7 May 2025 17:02:14 +0200 Subject: [PATCH 3/7] Fix linter issues --- packages/react-router/src/server/sdk.ts | 10 ++---- packages/react-router/test/server/sdk.test.ts | 33 +++++++------------ 2 files changed, 14 insertions(+), 29 deletions(-) diff --git a/packages/react-router/src/server/sdk.ts b/packages/react-router/src/server/sdk.ts index 1380f9af3235..995369a4663d 100644 --- a/packages/react-router/src/server/sdk.ts +++ b/packages/react-router/src/server/sdk.ts @@ -26,11 +26,7 @@ export function init(options: NodeOptions): NodeClient | undefined { return client; } -const matchedRegexes = [ - /GET \/node_modules\//, - /GET \/favicon\.ico/, - /GET \/@id\//, -]; +const matchedRegexes = [/GET \/node_modules\//, /GET \/favicon\.ico/, /GET \/@id\//]; /** * Filters out noisy transactions such as requests to node_modules, favicon.ico, @id/ @@ -41,14 +37,12 @@ const matchedRegexes = [ export function lowQualityTransactionsFilter(options: NodeOptions): EventProcessor { return Object.assign( (event => { - if (event.type !== 'transaction' || !event.transaction) { return event; } if (matchedRegexes.some(regex => event.transaction?.match(regex))) { - options.debug && - logger.log('[ReactRouter] Filtered node_modules transaction:', event.transaction); + options.debug && logger.log('[ReactRouter] Filtered node_modules transaction:', event.transaction); return null; } diff --git a/packages/react-router/test/server/sdk.test.ts b/packages/react-router/test/server/sdk.test.ts index cb4423b5e2c0..e8dbbf426077 100644 --- a/packages/react-router/test/server/sdk.test.ts +++ b/packages/react-router/test/server/sdk.test.ts @@ -80,34 +80,25 @@ describe('React Router server SDK', () => { }); describe('filters out low quality transactions', () => { - it.each([ - 'GET /node_modules/react/index.js', - 'GET /favicon.ico', - 'GET /@id/package', - ])('%s', async (transaction) => { - client.captureEvent({ type: 'transaction', transaction }); + it.each(['GET /node_modules/react/index.js', 'GET /favicon.ico', 'GET /@id/package'])( + '%s', + async transaction => { + client.captureEvent({ type: 'transaction', transaction }); - await client.flush(); + await client.flush(); - expect(beforeSendEvent).not.toHaveBeenCalled(); - }); + expect(beforeSendEvent).not.toHaveBeenCalled(); + }, + ); }); describe('allows high quality transactions', () => { - it.each([ - 'GET /', - 'GET /users', - 'POST /api/data', - 'GET /projects/123', - ])('%s', async (transaction) => { + it.each(['GET /', 'GET /users', 'POST /api/data', 'GET /projects/123'])('%s', async transaction => { client.captureEvent({ type: 'transaction', transaction }); await client.flush(); - expect(beforeSendEvent).toHaveBeenCalledWith( - expect.objectContaining({ transaction }), - expect.any(Object) - ); + expect(beforeSendEvent).toHaveBeenCalledWith(expect.objectContaining({ transaction }), expect.any(Object)); }); }); }); @@ -118,7 +109,7 @@ describe('React Router server SDK', () => { it.each([ ['node_modules request', 'GET /node_modules/react/index.js'], ['favicon.ico request', 'GET /favicon.ico'], - ['@id request', 'GET /@id/package'] + ['@id request', 'GET /@id/package'], ])('%s', (description, transaction) => { const filter = lowQualityTransactionsFilter({}); const event = { @@ -134,7 +125,7 @@ describe('React Router server SDK', () => { it.each([ ['normal page request', 'GET /users'], ['API request', 'POST /api/users'], - ['app route', 'GET /projects/123'] + ['app route', 'GET /projects/123'], ])('%s', (description, transaction) => { const filter = lowQualityTransactionsFilter({}); const event = { From e4fe07f8837b0348b5ca2be84d3b46cdc0389f4a Mon Sep 17 00:00:00 2001 From: RulaKhaled Date: Wed, 7 May 2025 17:15:45 +0200 Subject: [PATCH 4/7] fix imports for linter --- packages/react-router/test/server/sdk.test.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/react-router/test/server/sdk.test.ts b/packages/react-router/test/server/sdk.test.ts index e8dbbf426077..50f1cbce022d 100644 --- a/packages/react-router/test/server/sdk.test.ts +++ b/packages/react-router/test/server/sdk.test.ts @@ -1,11 +1,9 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; - -import { getGlobalScope } from '@sentry/core'; import type { Event, EventType } from '@sentry/core'; -import * as SentryNode from '@sentry/node'; +import { getGlobalScope } from '@sentry/core'; import type { NodeClient } from '@sentry/node'; +import * as SentryNode from '@sentry/node'; import { SDK_VERSION } from '@sentry/node'; - +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { init as reactRouterInit, lowQualityTransactionsFilter } from '../../src/server/sdk'; const nodeInit = vi.spyOn(SentryNode, 'init'); From 79ec0d632454055c5c2bb432a7e4c8f2c7cf12e3 Mon Sep 17 00:00:00 2001 From: RulaKhaled Date: Thu, 8 May 2025 11:53:30 +0200 Subject: [PATCH 5/7] Update low quality transaction filter to an integration in react-router --- ...lowQualityTransactionsFilterIntegration.ts | 36 +++++++ packages/react-router/src/server/sdk.ts | 42 +++----- ...alityTransactionsFilterIntegration.test.ts | 69 ++++++++++++++ packages/react-router/test/server/sdk.test.ts | 95 ++++--------------- 4 files changed, 133 insertions(+), 109 deletions(-) create mode 100644 packages/react-router/src/server/lowQualityTransactionsFilterIntegration.ts create mode 100644 packages/react-router/test/server/lowQualityTransactionsFilterIntegration.test.ts diff --git a/packages/react-router/src/server/lowQualityTransactionsFilterIntegration.ts b/packages/react-router/src/server/lowQualityTransactionsFilterIntegration.ts new file mode 100644 index 000000000000..69372b598cef --- /dev/null +++ b/packages/react-router/src/server/lowQualityTransactionsFilterIntegration.ts @@ -0,0 +1,36 @@ +import { type Client,type Event, type EventHint, defineIntegration, logger } from '@sentry/core'; +import type { NodeOptions } from '@sentry/node'; + +/** + * Integration that filters out noisy http transactions such as requests to node_modules, favicon.ico, @id/ + * + */ + +function _lowQualityTransactionsFilterIntegration(options: NodeOptions): { + name: string; + processEvent: (event: Event, hint: EventHint, client: Client) => Event | null; +} { + const matchedRegexes = [/GET \/node_modules\//, /GET \/favicon\.ico/, /GET \/@id\//]; + + return { + name: 'LowQualityTransactionsFilter', + + processEvent(event: Event, _hint: EventHint, _client: Client): Event | null { + if (event.type !== 'transaction' || !event.transaction) { + return event; + } + + if (matchedRegexes.some(regex => event.transaction?.match(regex))) { + options.debug && logger.log('[ReactRouter] Filtered node_modules transaction:', event.transaction); + return null; + } + + return event; + }, + }; +} + + +export const lowQualityTransactionsFilterIntegration = defineIntegration( + (options: NodeOptions) => _lowQualityTransactionsFilterIntegration(options), +); diff --git a/packages/react-router/src/server/sdk.ts b/packages/react-router/src/server/sdk.ts index 995369a4663d..fc0fb6cb34b4 100644 --- a/packages/react-router/src/server/sdk.ts +++ b/packages/react-router/src/server/sdk.ts @@ -1,7 +1,16 @@ -import { type EventProcessor, applySdkMetadata, getGlobalScope, logger, setTag } from '@sentry/core'; +import type { Integration} from '@sentry/core'; +import { applySdkMetadata, logger, setTag } from '@sentry/core'; import type { NodeClient, NodeOptions } from '@sentry/node'; -import { init as initNodeSdk } from '@sentry/node'; +import { getDefaultIntegrations as getNodeDefaultIntegrations,init as initNodeSdk} from '@sentry/node'; import { DEBUG_BUILD } from '../common/debug-build'; +import { lowQualityTransactionsFilterIntegration } from './lowQualityTransactionsFilterIntegration'; + +function getDefaultIntegrations(options: NodeOptions): Integration[] { + return [ + ... getNodeDefaultIntegrations(options), + lowQualityTransactionsFilterIntegration(options), + ]; +} /** * Initializes the server side of the React Router SDK @@ -9,6 +18,7 @@ import { DEBUG_BUILD } from '../common/debug-build'; export function init(options: NodeOptions): NodeClient | undefined { const opts = { ...options, + defaultIntegrations: getDefaultIntegrations(options), }; DEBUG_BUILD && logger.log('Initializing SDK...'); @@ -21,33 +31,5 @@ export function init(options: NodeOptions): NodeClient | undefined { DEBUG_BUILD && logger.log('SDK successfully initialized'); - getGlobalScope().addEventProcessor(lowQualityTransactionsFilter(options)); - return client; } - -const matchedRegexes = [/GET \/node_modules\//, /GET \/favicon\.ico/, /GET \/@id\//]; - -/** - * Filters out noisy transactions such as requests to node_modules, favicon.ico, @id/ - * - * @param options The NodeOptions passed to the SDK - * @returns An EventProcessor that filters low-quality transactions - */ -export function lowQualityTransactionsFilter(options: NodeOptions): EventProcessor { - return Object.assign( - (event => { - if (event.type !== 'transaction' || !event.transaction) { - return event; - } - - if (matchedRegexes.some(regex => event.transaction?.match(regex))) { - options.debug && logger.log('[ReactRouter] Filtered node_modules transaction:', event.transaction); - return null; - } - - return event; - }) satisfies EventProcessor, - { id: 'ReactRouterLowQualityTransactionsFilter' }, - ); -} diff --git a/packages/react-router/test/server/lowQualityTransactionsFilterIntegration.test.ts b/packages/react-router/test/server/lowQualityTransactionsFilterIntegration.test.ts new file mode 100644 index 000000000000..0e0c86b4b68a --- /dev/null +++ b/packages/react-router/test/server/lowQualityTransactionsFilterIntegration.test.ts @@ -0,0 +1,69 @@ +import type { Event, EventType, Integration } from '@sentry/core'; +import * as SentryCore from '@sentry/core'; +import * as SentryNode from '@sentry/node'; +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { lowQualityTransactionsFilterIntegration } from '../../src/server/lowQualityTransactionsFilterIntegration'; + +const loggerLog = vi.spyOn(SentryCore.logger, 'log').mockImplementation(() => {}); + +describe('Low Quality Transactions Filter Integration', () => { + afterEach(() => { + vi.clearAllMocks(); + SentryNode.getGlobalScope().clear(); + }); + + describe('integration functionality', () => { + describe('filters out low quality transactions', () => { + it.each([ + ['node_modules requests', 'GET /node_modules/some-package/index.js'], + ['favicon.ico requests', 'GET /favicon.ico'], + ['@id/ requests', 'GET /@id/some-id'] + ])('%s', (description, transaction) => { + const integration = lowQualityTransactionsFilterIntegration({ debug: true }) as Integration; + const event = { + type: 'transaction' as EventType, + transaction, + } as Event; + + const result = integration.processEvent!(event, {}, {} as SentryCore.Client); + + expect(result).toBeNull(); + + expect(loggerLog).toHaveBeenCalledWith( + '[ReactRouter] Filtered node_modules transaction:', + transaction + ); + }); + }); + + describe('allows high quality transactions', () => { + it.each([ + ['normal page requests', 'GET /api/users'], + ['API endpoints', 'POST /data'], + ['app routes', 'GET /projects/123'] + ])('%s', (description, transaction) => { + const integration = lowQualityTransactionsFilterIntegration({}) as Integration; + const event = { + type: 'transaction' as EventType, + transaction, + } as Event; + + const result = integration.processEvent!(event, {}, {} as SentryCore.Client); + + expect(result).toEqual(event); + }); + }); + + it('does not affect non-transaction events', () => { + const integration = lowQualityTransactionsFilterIntegration({}) as Integration; + const event = { + type: 'error' as EventType, + transaction: 'GET /node_modules/some-package/index.js', + } as Event; + + const result = integration.processEvent!(event, {}, {} as SentryCore.Client); + + expect(result).toEqual(event); + }); + }); +}); diff --git a/packages/react-router/test/server/sdk.test.ts b/packages/react-router/test/server/sdk.test.ts index 50f1cbce022d..0c6abd109d5f 100644 --- a/packages/react-router/test/server/sdk.test.ts +++ b/packages/react-router/test/server/sdk.test.ts @@ -1,10 +1,10 @@ -import type { Event, EventType } from '@sentry/core'; -import { getGlobalScope } from '@sentry/core'; +import type { Integration } from '@sentry/core'; import type { NodeClient } from '@sentry/node'; import * as SentryNode from '@sentry/node'; import { SDK_VERSION } from '@sentry/node'; -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import { init as reactRouterInit, lowQualityTransactionsFilter } from '../../src/server/sdk'; +import { afterEach, describe, expect, it, vi } from 'vitest'; +import * as LowQualityModule from '../../src/server/lowQualityTransactionsFilterIntegration'; +import { init as reactRouterInit } from '../../src/server/sdk'; const nodeInit = vi.spyOn(SentryNode, 'init'); @@ -48,91 +48,28 @@ describe('React Router server SDK', () => { expect(client).not.toBeUndefined(); }); - it('registers the low quality transactions filter', async () => { - const addEventProcessor = vi.spyOn(getGlobalScope(), 'addEventProcessor'); - addEventProcessor.mockClear(); + it('adds the low quality transactions filter integration by default', () => { + const filterSpy = vi.spyOn(LowQualityModule, 'lowQualityTransactionsFilterIntegration'); reactRouterInit({ dsn: 'https://public@dsn.ingest.sentry.io/1337', - }) as NodeClient; - - expect(addEventProcessor).toHaveBeenCalledTimes(1); - const processor = addEventProcessor.mock.calls[0]![0]; - expect(processor?.id).toEqual('ReactRouterLowQualityTransactionsFilter'); - }); - - describe('transaction filtering', () => { - const beforeSendEvent = vi.fn(event => event); - let client: NodeClient; - - beforeEach(() => { - vi.clearAllMocks(); - beforeSendEvent.mockClear(); - SentryNode.getGlobalScope().clear(); - - client = reactRouterInit({ - dsn: 'https://public@dsn.ingest.sentry.io/1337', - }) as NodeClient; - - client.on('beforeSendEvent', beforeSendEvent); }); - describe('filters out low quality transactions', () => { - it.each(['GET /node_modules/react/index.js', 'GET /favicon.ico', 'GET /@id/package'])( - '%s', - async transaction => { - client.captureEvent({ type: 'transaction', transaction }); - - await client.flush(); - - expect(beforeSendEvent).not.toHaveBeenCalled(); - }, - ); - }); + expect(filterSpy).toHaveBeenCalled(); - describe('allows high quality transactions', () => { - it.each(['GET /', 'GET /users', 'POST /api/data', 'GET /projects/123'])('%s', async transaction => { - client.captureEvent({ type: 'transaction', transaction }); - - await client.flush(); - - expect(beforeSendEvent).toHaveBeenCalledWith(expect.objectContaining({ transaction }), expect.any(Object)); - }); - }); - }); - }); + expect(nodeInit).toHaveBeenCalledTimes(1); + const initOptions = nodeInit.mock.calls[0]?.[0]; - describe('lowQualityTransactionsFilter', () => { - describe('filters out low quality transactions', () => { - it.each([ - ['node_modules request', 'GET /node_modules/react/index.js'], - ['favicon.ico request', 'GET /favicon.ico'], - ['@id request', 'GET /@id/package'], - ])('%s', (description, transaction) => { - const filter = lowQualityTransactionsFilter({}); - const event = { - type: 'transaction' as EventType, - transaction, - } as Event; + expect(initOptions).toBeDefined(); - expect(filter(event, {})).toBeNull(); - }); - }); + const defaultIntegrations = initOptions?.defaultIntegrations as Integration[]; + expect(Array.isArray(defaultIntegrations)).toBe(true); - describe('does not filter good transactions', () => { - it.each([ - ['normal page request', 'GET /users'], - ['API request', 'POST /api/users'], - ['app route', 'GET /projects/123'], - ])('%s', (description, transaction) => { - const filter = lowQualityTransactionsFilter({}); - const event = { - type: 'transaction' as EventType, - transaction, - } as Event; + const filterIntegration = defaultIntegrations.find( + integration => integration.name === 'LowQualityTransactionsFilter' + ); - expect(filter(event, {})).toBe(event); - }); + expect(filterIntegration).toBeDefined(); }); }); }); From f8623907a272d7f0cec3a285c053c1ac648c6095 Mon Sep 17 00:00:00 2001 From: RulaKhaled Date: Thu, 8 May 2025 12:00:56 +0200 Subject: [PATCH 6/7] Fix linter issues --- .../server/lowQualityTransactionsFilterIntegration.ts | 7 +++---- packages/react-router/src/server/sdk.ts | 9 +++------ .../lowQualityTransactionsFilterIntegration.test.ts | 9 +++------ packages/react-router/test/server/sdk.test.ts | 2 +- 4 files changed, 10 insertions(+), 17 deletions(-) diff --git a/packages/react-router/src/server/lowQualityTransactionsFilterIntegration.ts b/packages/react-router/src/server/lowQualityTransactionsFilterIntegration.ts index 69372b598cef..ecf6695f5524 100644 --- a/packages/react-router/src/server/lowQualityTransactionsFilterIntegration.ts +++ b/packages/react-router/src/server/lowQualityTransactionsFilterIntegration.ts @@ -1,4 +1,4 @@ -import { type Client,type Event, type EventHint, defineIntegration, logger } from '@sentry/core'; +import { type Client, type Event, type EventHint, defineIntegration, logger } from '@sentry/core'; import type { NodeOptions } from '@sentry/node'; /** @@ -30,7 +30,6 @@ function _lowQualityTransactionsFilterIntegration(options: NodeOptions): { }; } - -export const lowQualityTransactionsFilterIntegration = defineIntegration( - (options: NodeOptions) => _lowQualityTransactionsFilterIntegration(options), +export const lowQualityTransactionsFilterIntegration = defineIntegration((options: NodeOptions) => + _lowQualityTransactionsFilterIntegration(options), ); diff --git a/packages/react-router/src/server/sdk.ts b/packages/react-router/src/server/sdk.ts index fc0fb6cb34b4..c980078ac7b5 100644 --- a/packages/react-router/src/server/sdk.ts +++ b/packages/react-router/src/server/sdk.ts @@ -1,15 +1,12 @@ -import type { Integration} from '@sentry/core'; +import type { Integration } from '@sentry/core'; import { applySdkMetadata, logger, setTag } from '@sentry/core'; import type { NodeClient, NodeOptions } from '@sentry/node'; -import { getDefaultIntegrations as getNodeDefaultIntegrations,init as initNodeSdk} from '@sentry/node'; +import { getDefaultIntegrations as getNodeDefaultIntegrations, init as initNodeSdk } from '@sentry/node'; import { DEBUG_BUILD } from '../common/debug-build'; import { lowQualityTransactionsFilterIntegration } from './lowQualityTransactionsFilterIntegration'; function getDefaultIntegrations(options: NodeOptions): Integration[] { - return [ - ... getNodeDefaultIntegrations(options), - lowQualityTransactionsFilterIntegration(options), - ]; + return [...getNodeDefaultIntegrations(options), lowQualityTransactionsFilterIntegration(options)]; } /** diff --git a/packages/react-router/test/server/lowQualityTransactionsFilterIntegration.test.ts b/packages/react-router/test/server/lowQualityTransactionsFilterIntegration.test.ts index 0e0c86b4b68a..58ddf3e215d6 100644 --- a/packages/react-router/test/server/lowQualityTransactionsFilterIntegration.test.ts +++ b/packages/react-router/test/server/lowQualityTransactionsFilterIntegration.test.ts @@ -17,7 +17,7 @@ describe('Low Quality Transactions Filter Integration', () => { it.each([ ['node_modules requests', 'GET /node_modules/some-package/index.js'], ['favicon.ico requests', 'GET /favicon.ico'], - ['@id/ requests', 'GET /@id/some-id'] + ['@id/ requests', 'GET /@id/some-id'], ])('%s', (description, transaction) => { const integration = lowQualityTransactionsFilterIntegration({ debug: true }) as Integration; const event = { @@ -29,10 +29,7 @@ describe('Low Quality Transactions Filter Integration', () => { expect(result).toBeNull(); - expect(loggerLog).toHaveBeenCalledWith( - '[ReactRouter] Filtered node_modules transaction:', - transaction - ); + expect(loggerLog).toHaveBeenCalledWith('[ReactRouter] Filtered node_modules transaction:', transaction); }); }); @@ -40,7 +37,7 @@ describe('Low Quality Transactions Filter Integration', () => { it.each([ ['normal page requests', 'GET /api/users'], ['API endpoints', 'POST /data'], - ['app routes', 'GET /projects/123'] + ['app routes', 'GET /projects/123'], ])('%s', (description, transaction) => { const integration = lowQualityTransactionsFilterIntegration({}) as Integration; const event = { diff --git a/packages/react-router/test/server/sdk.test.ts b/packages/react-router/test/server/sdk.test.ts index 0c6abd109d5f..57b51d16c042 100644 --- a/packages/react-router/test/server/sdk.test.ts +++ b/packages/react-router/test/server/sdk.test.ts @@ -66,7 +66,7 @@ describe('React Router server SDK', () => { expect(Array.isArray(defaultIntegrations)).toBe(true); const filterIntegration = defaultIntegrations.find( - integration => integration.name === 'LowQualityTransactionsFilter' + integration => integration.name === 'LowQualityTransactionsFilter', ); expect(filterIntegration).toBeDefined(); From caf789ae86d5c4dcae4a11017ca402935c3e150a Mon Sep 17 00:00:00 2001 From: RulaKhaled Date: Fri, 9 May 2025 15:34:57 +0200 Subject: [PATCH 7/7] Resolve undefined typescript issue --- .../src/server/lowQualityTransactionsFilterIntegration.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/react-router/src/server/lowQualityTransactionsFilterIntegration.ts b/packages/react-router/src/server/lowQualityTransactionsFilterIntegration.ts index ecf6695f5524..705359eab62c 100644 --- a/packages/react-router/src/server/lowQualityTransactionsFilterIntegration.ts +++ b/packages/react-router/src/server/lowQualityTransactionsFilterIntegration.ts @@ -20,7 +20,9 @@ function _lowQualityTransactionsFilterIntegration(options: NodeOptions): { return event; } - if (matchedRegexes.some(regex => event.transaction?.match(regex))) { + const transaction = event.transaction; + + if (matchedRegexes.some(regex => transaction.match(regex))) { options.debug && logger.log('[ReactRouter] Filtered node_modules transaction:', event.transaction); return null; }