From b783be8dce5054b98b295c2caed9e779b1397ef9 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 17 May 2026 15:06:17 +0000 Subject: [PATCH 1/3] Clean up Sentry noise Co-authored-by: Kent C. Dodds --- packages/workshop-app/app/routes/$.tsx | 4 ++ .../app/utils/monitoring.client.ts | 3 ++ .../workshop-app/app/utils/sentry-filters.ts | 25 ++++++++++ .../tests/catchall-route.browser.test.ts | 9 ++++ .../tests/sentry-filters.browser.test.ts | 50 +++++++++++++++++++ 5 files changed, 91 insertions(+) create mode 100644 packages/workshop-app/app/utils/sentry-filters.ts create mode 100644 packages/workshop-app/tests/catchall-route.browser.test.ts create mode 100644 packages/workshop-app/tests/sentry-filters.browser.test.ts diff --git a/packages/workshop-app/app/routes/$.tsx b/packages/workshop-app/app/routes/$.tsx index 35301e06..f0f81394 100644 --- a/packages/workshop-app/app/routes/$.tsx +++ b/packages/workshop-app/app/routes/$.tsx @@ -26,6 +26,10 @@ export async function loader({ params }: Route.LoaderArgs) { throw new Response('Not found', { status: 404 }) } +export function action() { + return new Response('Not found', { status: 404 }) +} + export default function NotFound() { // due to the loader, this component will never be rendered, but we'll return // the error boundary just in case. diff --git a/packages/workshop-app/app/utils/monitoring.client.ts b/packages/workshop-app/app/utils/monitoring.client.ts index e858ae4e..162c9db6 100644 --- a/packages/workshop-app/app/utils/monitoring.client.ts +++ b/packages/workshop-app/app/utils/monitoring.client.ts @@ -5,6 +5,7 @@ import { useLocation, useNavigationType, } from 'react-router' +import { isProcessingPictureInPictureRequest } from './sentry-filters.ts' // Dynamic import of Sentry with error handling const Sentry = await import('@sentry/react-router').catch((error) => { @@ -104,6 +105,8 @@ export function init() { "Failed to execute 'requestPictureInPicture' on 'HTMLVideoElement'", ], beforeSend(event) { + if (isProcessingPictureInPictureRequest(event)) return null + // Don't send errors to Sentry for bot requests if (typeof navigator !== 'undefined' && navigator.userAgent) { // Basic bot detection for client-side - check for common bot indicators diff --git a/packages/workshop-app/app/utils/sentry-filters.ts b/packages/workshop-app/app/utils/sentry-filters.ts new file mode 100644 index 00000000..709cb8ce --- /dev/null +++ b/packages/workshop-app/app/utils/sentry-filters.ts @@ -0,0 +1,25 @@ +type SentryExceptionValue = { + type?: string + value?: string +} + +type SentryEventWithException = { + exception?: { + values?: Array + } +} + +export const processingPictureInPictureRequestMessage = + 'The video element is processing a Picture-in-Picture request.' + +export function isProcessingPictureInPictureRequest( + event: SentryEventWithException, +) { + return ( + event.exception?.values?.some( + (value) => + value.type === 'NotAllowedError' && + value.value === processingPictureInPictureRequestMessage, + ) ?? false + ) +} diff --git a/packages/workshop-app/tests/catchall-route.browser.test.ts b/packages/workshop-app/tests/catchall-route.browser.test.ts new file mode 100644 index 00000000..b3c2f1de --- /dev/null +++ b/packages/workshop-app/tests/catchall-route.browser.test.ts @@ -0,0 +1,9 @@ +import { expect, test } from 'vitest' +import { action } from '../app/routes/$.tsx' + +test('returns a plain 404 for scanner POSTs to catch-all paths', async () => { + const response = action() + + expect(response.status).toBe(404) + await expect(response.text()).resolves.toBe('Not found') +}) diff --git a/packages/workshop-app/tests/sentry-filters.browser.test.ts b/packages/workshop-app/tests/sentry-filters.browser.test.ts new file mode 100644 index 00000000..aad75218 --- /dev/null +++ b/packages/workshop-app/tests/sentry-filters.browser.test.ts @@ -0,0 +1,50 @@ +import { expect, test } from 'vitest' +import { + isProcessingPictureInPictureRequest, + processingPictureInPictureRequestMessage, +} from '../app/utils/sentry-filters.ts' + +test('matches the Picture-in-Picture processing DOMException exactly', () => { + expect( + isProcessingPictureInPictureRequest({ + exception: { + values: [ + { + type: 'NotAllowedError', + value: processingPictureInPictureRequestMessage, + }, + ], + }, + }), + ).toBe(true) +}) + +test('does not match unrelated NotAllowedError exceptions', () => { + expect( + isProcessingPictureInPictureRequest({ + exception: { + values: [ + { + type: 'NotAllowedError', + value: 'Permission denied.', + }, + ], + }, + }), + ).toBe(false) +}) + +test('does not match the same message on a different exception type', () => { + expect( + isProcessingPictureInPictureRequest({ + exception: { + values: [ + { + type: 'SecurityError', + value: processingPictureInPictureRequestMessage, + }, + ], + }, + }), + ).toBe(false) +}) From 9d00a27a381310c7fda17ba396a00f65afb61692 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 17 May 2026 15:11:32 +0000 Subject: [PATCH 2/3] Run Sentry noise tests in Vitest Co-authored-by: Kent C. Dodds --- ...route.browser.test.ts => catchall-route.test.ts} | 0 ...lters.browser.test.ts => sentry-filters.test.ts} | 0 packages/workshop-app/vitest.sentry-noise.config.ts | 13 +++++++++++++ vitest.config.ts | 1 + 4 files changed, 14 insertions(+) rename packages/workshop-app/tests/{catchall-route.browser.test.ts => catchall-route.test.ts} (100%) rename packages/workshop-app/tests/{sentry-filters.browser.test.ts => sentry-filters.test.ts} (100%) create mode 100644 packages/workshop-app/vitest.sentry-noise.config.ts diff --git a/packages/workshop-app/tests/catchall-route.browser.test.ts b/packages/workshop-app/tests/catchall-route.test.ts similarity index 100% rename from packages/workshop-app/tests/catchall-route.browser.test.ts rename to packages/workshop-app/tests/catchall-route.test.ts diff --git a/packages/workshop-app/tests/sentry-filters.browser.test.ts b/packages/workshop-app/tests/sentry-filters.test.ts similarity index 100% rename from packages/workshop-app/tests/sentry-filters.browser.test.ts rename to packages/workshop-app/tests/sentry-filters.test.ts diff --git a/packages/workshop-app/vitest.sentry-noise.config.ts b/packages/workshop-app/vitest.sentry-noise.config.ts new file mode 100644 index 00000000..0b17485e --- /dev/null +++ b/packages/workshop-app/vitest.sentry-noise.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + name: 'app-sentry-noise', + include: [ + 'tests/catchall-route.test.ts', + 'tests/sentry-filters.test.ts', + ], + setupFiles: ['../../tests/vitest-setup.ts'], + mockReset: true, + }, +}) diff --git a/vitest.config.ts b/vitest.config.ts index c2ceba8d..a3d016e8 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -3,6 +3,7 @@ import { defineConfig } from 'vitest/config' export default defineConfig({ test: { projects: [ + './packages/workshop-app/vitest.sentry-noise.config.ts', './packages/workshop-app', './packages/workshop-utils', './packages/workshop-presence', From c0ab2dc1c10e23cdab7d38d58c105b9566502e03 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 17 May 2026 15:12:50 +0000 Subject: [PATCH 3/3] Format Sentry noise test config Co-authored-by: Kent C. Dodds --- packages/workshop-app/vitest.sentry-noise.config.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/workshop-app/vitest.sentry-noise.config.ts b/packages/workshop-app/vitest.sentry-noise.config.ts index 0b17485e..ef06628b 100644 --- a/packages/workshop-app/vitest.sentry-noise.config.ts +++ b/packages/workshop-app/vitest.sentry-noise.config.ts @@ -3,10 +3,7 @@ import { defineConfig } from 'vitest/config' export default defineConfig({ test: { name: 'app-sentry-noise', - include: [ - 'tests/catchall-route.test.ts', - 'tests/sentry-filters.test.ts', - ], + include: ['tests/catchall-route.test.ts', 'tests/sentry-filters.test.ts'], setupFiles: ['../../tests/vitest-setup.ts'], mockReset: true, },