From 26e519d39eb0a271d69c654617129de6c1e7df8e Mon Sep 17 00:00:00 2001 From: s1gr1d <32902192+s1gr1d@users.noreply.github.com> Date: Wed, 21 Oct 2026 11:24:21 +0200 Subject: [PATCH 1/2] feat(nextjs): Warn when the instrumentation file is in the wrong folder --- .../withSentryConfig/getFinalConfigObject.ts | 2 + .../getFinalConfigObjectUtils.ts | 46 +++++++- .../getFinalConfigObjectUtils.test.ts | 102 ++++++++++++++++++ 3 files changed, 149 insertions(+), 1 deletion(-) diff --git a/packages/nextjs/src/config/withSentryConfig/getFinalConfigObject.ts b/packages/nextjs/src/config/withSentryConfig/getFinalConfigObject.ts index fb1b9f616aeb..33b53c7dd950 100644 --- a/packages/nextjs/src/config/withSentryConfig/getFinalConfigObject.ts +++ b/packages/nextjs/src/config/withSentryConfig/getFinalConfigObject.ts @@ -25,6 +25,7 @@ import { maybeSetUpTunnelRouteRewriteRules, resolveReleaseName, shouldReturnEarlyInExperimentalBuildMode, + warnIfMisplacedInstrumentationFile, warnIfMissingOnRouterTransitionStartHook, } from './getFinalConfigObjectUtils'; @@ -55,6 +56,7 @@ export function getFinalConfigObject( maybeSetClientTraceMetadataOption(incomingUserNextConfigObject, nextJsVersion, userSentryOptions.silent); maybeSetInstrumentationHookOption(incomingUserNextConfigObject, nextJsVersion, userSentryOptions.silent); warnIfMissingOnRouterTransitionStartHook(userSentryOptions); + warnIfMisplacedInstrumentationFile(incomingUserNextConfigObject, userSentryOptions); const bundlerInfo = getBundlerInfo(nextJsVersion); maybeWarnAboutUnsupportedTurbopack(nextJsVersion, bundlerInfo, userSentryOptions.silent); diff --git a/packages/nextjs/src/config/withSentryConfig/getFinalConfigObjectUtils.ts b/packages/nextjs/src/config/withSentryConfig/getFinalConfigObjectUtils.ts index 68520bc1e16d..5f70094efb3c 100644 --- a/packages/nextjs/src/config/withSentryConfig/getFinalConfigObjectUtils.ts +++ b/packages/nextjs/src/config/withSentryConfig/getFinalConfigObjectUtils.ts @@ -7,7 +7,7 @@ import { getBuildLogger } from '../buildLogger'; import { createRouteManifest } from '../manifest/createRouteManifest'; import type { RouteManifest } from '../manifest/types'; import type { NextConfigObject, SentryBuildOptions } from '../types'; -import { requiresInstrumentationHook } from '../util'; +import { DEFAULT_PAGE_EXTENSIONS, requiresInstrumentationHook } from '../util'; import { getGitRevision, getInstrumentationClientFileContents } from './buildTime'; import { findTunnelRouteHandlerFile, @@ -21,6 +21,8 @@ let showedUnusedTunnelRouteHandlerWarning = false; let showedTunnelRouteHandlerModeLog = false; let showedExperimentalBuildModeWarning = false; +const MISPLACED_INSTRUMENTATION_FILE_WARNING_SHOWN = '__SENTRY_MISPLACED_INSTRUMENTATION_FILE_WARNING_SHOWN__'; + /** * Resolves the Sentry release name to use for build-time behavior. * @@ -266,6 +268,48 @@ export function warnIfMissingOnRouterTransitionStartHook(userSentryOptions: Sent } } +/** + * Warns if the `instrumentation` file is not in the folder that contains the `app` or `pages` directory. + * `next build` only looks there, even though dev and Turbopack also find the file in other places. + */ +export function warnIfMisplacedInstrumentationFile( + incomingUserNextConfigObject: NextConfigObject, + userSentryOptions: SentryBuildOptions, +): void { + if ( + process.env[MISPLACED_INSTRUMENTATION_FILE_WARNING_SHOWN] || + process.env.SENTRY_SUPPRESS_INSTRUMENTATION_FILE_WARNING + ) { + return; + } + + const projectDir = process.cwd(); + const exists = (relativePath: string): boolean => fs.existsSync(path.join(projectDir, relativePath)); + + // Same lookup as Next.js' `findPagesDir`: `pages` before `app`, and `` before `src/`. + const routerDir = ['pages', 'app'].flatMap(name => [name, path.join('src', name)]).find(exists); + if (!routerDir) { + return; + } + + const loadedDir = path.dirname(routerDir); + const ignoredDir = loadedDir === 'src' ? '.' : 'src'; + const pageExtensions = incomingUserNextConfigObject.pageExtensions ?? DEFAULT_PAGE_EXTENSIONS; + const findInstrumentationFile = (dir: string): string | undefined => + pageExtensions.map(extension => path.join(dir, `instrumentation.${extension}`)).find(exists); + + const misplacedFile = findInstrumentationFile(ignoredDir); + if (!misplacedFile || findInstrumentationFile(loadedDir)) { + return; + } + + // Next.js may evaluate its config in child processes, which inherit this state from their parent. + process.env[MISPLACED_INSTRUMENTATION_FILE_WARNING_SHOWN] = '1'; + getBuildLogger(userSentryOptions.silent).warn( + `[@sentry/nextjs] Found ${misplacedFile}, but Next.js production builds only pick up the instrumentation file next to your ${routerDir} directory. Move it to ${path.join(loadedDir, path.basename(misplacedFile))}, or the Sentry SDK may not be initialized on the server in production.`, + ); +} + /** * Parses the major Next.js version number from a semver string. */ diff --git a/packages/nextjs/test/config/withSentryConfig/getFinalConfigObjectUtils.test.ts b/packages/nextjs/test/config/withSentryConfig/getFinalConfigObjectUtils.test.ts index cfda40eaa28f..d056ea8d1b24 100644 --- a/packages/nextjs/test/config/withSentryConfig/getFinalConfigObjectUtils.test.ts +++ b/packages/nextjs/test/config/withSentryConfig/getFinalConfigObjectUtils.test.ts @@ -1,5 +1,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import type { NextConfigObject } from '../../../src/config/types'; +import { warnIfMisplacedInstrumentationFile } from '../../../src/config/withSentryConfig/getFinalConfigObjectUtils'; import { makeProject, removeProjects } from './projectFixture'; const HANDLER_REWRITE = { source: '/monitoring', destination: '/sentry-tunnel' }; @@ -121,3 +122,104 @@ describe('maybeSetUpTunnelRouteRewriteRules', () => { expect(warnSpy).not.toHaveBeenCalled(); }); }); + +describe('warnIfMisplacedInstrumentationFile', () => { + const ROOT_FILE_WITH_SRC_APP = ['src/app/page.tsx', 'instrumentation.ts']; + + beforeEach(() => { + vi.restoreAllMocks(); + vi.unstubAllEnvs(); + vi.stubEnv('__SENTRY_MISPLACED_INSTRUMENTATION_FILE_WARNING_SHOWN__', undefined); + }); + + function setUp(files: string[]) { + vi.spyOn(process, 'cwd').mockReturnValue(makeProject(files)); + return vi.spyOn(console, 'warn').mockImplementation(() => undefined); + } + + function misplacedFileWarning(found: string, routerDir: string, target: string): string { + return `[@sentry/nextjs] Found ${found}, but Next.js production builds only pick up the instrumentation file next to your ${routerDir} directory. Move it to ${target}, or the Sentry SDK may not be initialized on the server in production.`; + } + + it.each([ + { + found: 'instrumentation.ts', + routerDir: 'src/app', + target: 'src/instrumentation.ts', + files: ROOT_FILE_WITH_SRC_APP, + }, + { + found: 'instrumentation.js', + routerDir: 'src/pages', + target: 'src/instrumentation.js', + files: ['src/pages/index.tsx', 'instrumentation.js'], + }, + { + found: 'src/instrumentation.ts', + routerDir: 'app', + target: 'instrumentation.ts', + files: ['app/page.tsx', 'src/lib/db.ts', 'src/instrumentation.ts'], + }, + ])('warns about $found in a project with $routerDir', ({ found, routerDir, target, files }) => { + const warnSpy = setUp(files); + + warnIfMisplacedInstrumentationFile({}, {}); + + expect(warnSpy).toHaveBeenCalledTimes(1); + expect(warnSpy).toHaveBeenCalledWith(misplacedFileWarning(found, routerDir, target)); + }); + + it('looks for the file with the configured `pageExtensions`', () => { + const warnSpy = setUp(['src/app/page.page.tsx', 'instrumentation.page.ts']); + + warnIfMisplacedInstrumentationFile({ pageExtensions: ['page.tsx', 'page.ts'] }, {}); + + expect(warnSpy).toHaveBeenCalledTimes(1); + expect(warnSpy).toHaveBeenCalledWith( + misplacedFileWarning('instrumentation.page.ts', 'src/app', 'src/instrumentation.page.ts'), + ); + }); + + it('warns only once', () => { + const warnSpy = setUp(ROOT_FILE_WITH_SRC_APP); + + warnIfMisplacedInstrumentationFile({}, {}); + warnIfMisplacedInstrumentationFile({}, {}); + + expect(warnSpy).toHaveBeenCalledTimes(1); + }); + + it.each([ + ['the file is next to `src/app`', ['src/app/page.tsx', 'src/instrumentation.ts']], + ['the file is next to `app`', ['app/page.tsx', 'instrumentation.ts']], + ['a file is in both folders', ['src/app/page.tsx', 'src/instrumentation.ts', 'instrumentation.ts']], + [ + 'a root `pages` directory takes precedence over `src/app`', + ['pages/index.tsx', 'src/app/page.tsx', 'instrumentation.ts'], + ], + ['the project has no `app` or `pages` directory', ['instrumentation.ts']], + ])('does not warn when %s', (_setup, files) => { + const warnSpy = setUp(files); + + warnIfMisplacedInstrumentationFile({}, {}); + + expect(warnSpy).not.toHaveBeenCalled(); + }); + + it('does not warn with `silent`', () => { + const warnSpy = setUp(ROOT_FILE_WITH_SRC_APP); + + warnIfMisplacedInstrumentationFile({}, { silent: true }); + + expect(warnSpy).not.toHaveBeenCalled(); + }); + + it('does not warn when SENTRY_SUPPRESS_INSTRUMENTATION_FILE_WARNING is set', () => { + vi.stubEnv('SENTRY_SUPPRESS_INSTRUMENTATION_FILE_WARNING', '1'); + const warnSpy = setUp(ROOT_FILE_WITH_SRC_APP); + + warnIfMisplacedInstrumentationFile({}, {}); + + expect(warnSpy).not.toHaveBeenCalled(); + }); +}); From f46442d155f4da65f307dbaa4c299c6d558e34c2 Mon Sep 17 00:00:00 2001 From: s1gr1d <32902192+s1gr1d@users.noreply.github.com> Date: Fri, 23 Oct 2026 14:10:53 +0200 Subject: [PATCH 2/2] review suggestions --- packages/nextjs/src/config/webpack.ts | 15 +--- .../withSentryConfig/getFinalConfigObject.ts | 4 +- .../getFinalConfigObjectUtils.ts | 25 +++--- .../getFinalConfigObjectUtils.test.ts | 85 ++++++++----------- 4 files changed, 51 insertions(+), 78 deletions(-) diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index 32bd6bee28e7..b7c1efa5cb65 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -515,19 +515,8 @@ function getInstrumentationFile(projectDir: string, dotPrefixedExtensions: strin * Make sure the instrumentation file has a `onRequestError` Handler */ function warnAboutMissingOnRequestErrorHandler(instrumentationFile: string | null, silent?: boolean): void { - const logger = getBuildLogger(silent); - - if (!instrumentationFile) { - if (!process.env.SENTRY_SUPPRESS_INSTRUMENTATION_FILE_WARNING) { - logger.warn( - '[@sentry/nextjs] Could not find a Next.js instrumentation file. This indicates an incomplete configuration of the Sentry SDK. An instrumentation file is required for the Sentry SDK to be initialized on the server: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#create-initialization-config-files (you can suppress this warning by setting SENTRY_SUPPRESS_INSTRUMENTATION_FILE_WARNING=1 as environment variable)', - ); - } - return; - } - - if (!instrumentationFile.includes('onRequestError')) { - logger.warn( + if (instrumentationFile && !instrumentationFile.includes('onRequestError')) { + getBuildLogger(silent).warn( '[@sentry/nextjs] Could not find `onRequestError` hook in instrumentation file. This indicates outdated configuration of the Sentry SDK. Use `Sentry.captureRequestError` to instrument the `onRequestError` hook: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#errors-from-nested-react-server-components', ); } diff --git a/packages/nextjs/src/config/withSentryConfig/getFinalConfigObject.ts b/packages/nextjs/src/config/withSentryConfig/getFinalConfigObject.ts index 33b53c7dd950..e855041202e1 100644 --- a/packages/nextjs/src/config/withSentryConfig/getFinalConfigObject.ts +++ b/packages/nextjs/src/config/withSentryConfig/getFinalConfigObject.ts @@ -25,7 +25,7 @@ import { maybeSetUpTunnelRouteRewriteRules, resolveReleaseName, shouldReturnEarlyInExperimentalBuildMode, - warnIfMisplacedInstrumentationFile, + warnIfMissingInstrumentationFile, warnIfMissingOnRouterTransitionStartHook, } from './getFinalConfigObjectUtils'; @@ -56,7 +56,7 @@ export function getFinalConfigObject( maybeSetClientTraceMetadataOption(incomingUserNextConfigObject, nextJsVersion, userSentryOptions.silent); maybeSetInstrumentationHookOption(incomingUserNextConfigObject, nextJsVersion, userSentryOptions.silent); warnIfMissingOnRouterTransitionStartHook(userSentryOptions); - warnIfMisplacedInstrumentationFile(incomingUserNextConfigObject, userSentryOptions); + warnIfMissingInstrumentationFile(incomingUserNextConfigObject, userSentryOptions); const bundlerInfo = getBundlerInfo(nextJsVersion); maybeWarnAboutUnsupportedTurbopack(nextJsVersion, bundlerInfo, userSentryOptions.silent); diff --git a/packages/nextjs/src/config/withSentryConfig/getFinalConfigObjectUtils.ts b/packages/nextjs/src/config/withSentryConfig/getFinalConfigObjectUtils.ts index 5f70094efb3c..7ca66c51d1f7 100644 --- a/packages/nextjs/src/config/withSentryConfig/getFinalConfigObjectUtils.ts +++ b/packages/nextjs/src/config/withSentryConfig/getFinalConfigObjectUtils.ts @@ -21,7 +21,7 @@ let showedUnusedTunnelRouteHandlerWarning = false; let showedTunnelRouteHandlerModeLog = false; let showedExperimentalBuildModeWarning = false; -const MISPLACED_INSTRUMENTATION_FILE_WARNING_SHOWN = '__SENTRY_MISPLACED_INSTRUMENTATION_FILE_WARNING_SHOWN__'; +const MISSING_INSTRUMENTATION_FILE_WARNING_SHOWN = '__SENTRY_MISSING_INSTRUMENTATION_FILE_WARNING_SHOWN__'; /** * Resolves the Sentry release name to use for build-time behavior. @@ -269,15 +269,15 @@ export function warnIfMissingOnRouterTransitionStartHook(userSentryOptions: Sent } /** - * Warns if the `instrumentation` file is not in the folder that contains the `app` or `pages` directory. + * Warns if there is no `instrumentation` file next to the `app` or `pages` directory. * `next build` only looks there, even though dev and Turbopack also find the file in other places. */ -export function warnIfMisplacedInstrumentationFile( +export function warnIfMissingInstrumentationFile( incomingUserNextConfigObject: NextConfigObject, userSentryOptions: SentryBuildOptions, ): void { if ( - process.env[MISPLACED_INSTRUMENTATION_FILE_WARNING_SHOWN] || + process.env[MISSING_INSTRUMENTATION_FILE_WARNING_SHOWN] || process.env.SENTRY_SUPPRESS_INSTRUMENTATION_FILE_WARNING ) { return; @@ -286,27 +286,22 @@ export function warnIfMisplacedInstrumentationFile( const projectDir = process.cwd(); const exists = (relativePath: string): boolean => fs.existsSync(path.join(projectDir, relativePath)); - // Same lookup as Next.js' `findPagesDir`: `pages` before `app`, and `` before `src/`. - const routerDir = ['pages', 'app'].flatMap(name => [name, path.join('src', name)]).find(exists); + // Same order as Next.js' `findPagesDir` + const routerDir = ['pages', path.join('src', 'pages'), 'app', path.join('src', 'app')].find(exists); if (!routerDir) { return; } - const loadedDir = path.dirname(routerDir); - const ignoredDir = loadedDir === 'src' ? '.' : 'src'; + const instrumentationDir = path.dirname(routerDir); const pageExtensions = incomingUserNextConfigObject.pageExtensions ?? DEFAULT_PAGE_EXTENSIONS; - const findInstrumentationFile = (dir: string): string | undefined => - pageExtensions.map(extension => path.join(dir, `instrumentation.${extension}`)).find(exists); - - const misplacedFile = findInstrumentationFile(ignoredDir); - if (!misplacedFile || findInstrumentationFile(loadedDir)) { + if (pageExtensions.some(extension => exists(path.join(instrumentationDir, `instrumentation.${extension}`)))) { return; } // Next.js may evaluate its config in child processes, which inherit this state from their parent. - process.env[MISPLACED_INSTRUMENTATION_FILE_WARNING_SHOWN] = '1'; + process.env[MISSING_INSTRUMENTATION_FILE_WARNING_SHOWN] = '1'; getBuildLogger(userSentryOptions.silent).warn( - `[@sentry/nextjs] Found ${misplacedFile}, but Next.js production builds only pick up the instrumentation file next to your ${routerDir} directory. Move it to ${path.join(loadedDir, path.basename(misplacedFile))}, or the Sentry SDK may not be initialized on the server in production.`, + `[@sentry/nextjs] Could not find an instrumentation file next to your ${routerDir} directory. Next.js production builds only load it from there, so the Sentry SDK will not be initialized on the server. Create ${path.join(instrumentationDir, 'instrumentation.ts')}, or move your existing instrumentation file there: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#register-server-side-sdk (you can suppress this warning by setting SENTRY_SUPPRESS_INSTRUMENTATION_FILE_WARNING=1 as environment variable)`, ); } diff --git a/packages/nextjs/test/config/withSentryConfig/getFinalConfigObjectUtils.test.ts b/packages/nextjs/test/config/withSentryConfig/getFinalConfigObjectUtils.test.ts index d056ea8d1b24..273fddb96c01 100644 --- a/packages/nextjs/test/config/withSentryConfig/getFinalConfigObjectUtils.test.ts +++ b/packages/nextjs/test/config/withSentryConfig/getFinalConfigObjectUtils.test.ts @@ -1,6 +1,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import type { NextConfigObject } from '../../../src/config/types'; -import { warnIfMisplacedInstrumentationFile } from '../../../src/config/withSentryConfig/getFinalConfigObjectUtils'; +import { warnIfMissingInstrumentationFile } from '../../../src/config/withSentryConfig/getFinalConfigObjectUtils'; import { makeProject, removeProjects } from './projectFixture'; const HANDLER_REWRITE = { source: '/monitoring', destination: '/sentry-tunnel' }; @@ -123,13 +123,13 @@ describe('maybeSetUpTunnelRouteRewriteRules', () => { }); }); -describe('warnIfMisplacedInstrumentationFile', () => { +describe('warnIfMissingInstrumentationFile', () => { const ROOT_FILE_WITH_SRC_APP = ['src/app/page.tsx', 'instrumentation.ts']; beforeEach(() => { vi.restoreAllMocks(); vi.unstubAllEnvs(); - vi.stubEnv('__SENTRY_MISPLACED_INSTRUMENTATION_FILE_WARNING_SHOWN__', undefined); + vi.stubEnv('__SENTRY_MISSING_INSTRUMENTATION_FILE_WARNING_SHOWN__', undefined); }); function setUp(files: string[]) { @@ -137,71 +137,60 @@ describe('warnIfMisplacedInstrumentationFile', () => { return vi.spyOn(console, 'warn').mockImplementation(() => undefined); } - function misplacedFileWarning(found: string, routerDir: string, target: string): string { - return `[@sentry/nextjs] Found ${found}, but Next.js production builds only pick up the instrumentation file next to your ${routerDir} directory. Move it to ${target}, or the Sentry SDK may not be initialized on the server in production.`; + function missingFileWarning(routerDir: string, target: string): string { + return `[@sentry/nextjs] Could not find an instrumentation file next to your ${routerDir} directory. Next.js production builds only load it from there, so the Sentry SDK will not be initialized on the server. Create ${target}, or move your existing instrumentation file there: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#register-server-side-sdk (you can suppress this warning by setting SENTRY_SUPPRESS_INSTRUMENTATION_FILE_WARNING=1 as environment variable)`; } it.each([ - { - found: 'instrumentation.ts', - routerDir: 'src/app', - target: 'src/instrumentation.ts', - files: ROOT_FILE_WITH_SRC_APP, - }, - { - found: 'instrumentation.js', - routerDir: 'src/pages', - target: 'src/instrumentation.js', - files: ['src/pages/index.tsx', 'instrumentation.js'], - }, - { - found: 'src/instrumentation.ts', - routerDir: 'app', - target: 'instrumentation.ts', - files: ['app/page.tsx', 'src/lib/db.ts', 'src/instrumentation.ts'], - }, - ])('warns about $found in a project with $routerDir', ({ found, routerDir, target, files }) => { + ['the file is in the project root with `src/app`', ROOT_FILE_WITH_SRC_APP, 'src/app', 'src/instrumentation.ts'], + [ + 'the file is in `src` with `app`', + ['app/page.tsx', 'src/lib/db.ts', 'src/instrumentation.ts'], + 'app', + 'instrumentation.ts', + ], + ['there is no file with `src/pages`', ['src/pages/index.tsx'], 'src/pages', 'src/instrumentation.ts'], + [ + 'the file is next to `src/app`, but a root `pages` directory takes precedence', + ['pages/index.tsx', 'src/app/page.tsx', 'src/instrumentation.ts'], + 'pages', + 'instrumentation.ts', + ], + ])('warns when %s', (_setup, files, routerDir, target) => { const warnSpy = setUp(files); - warnIfMisplacedInstrumentationFile({}, {}); - - expect(warnSpy).toHaveBeenCalledTimes(1); - expect(warnSpy).toHaveBeenCalledWith(misplacedFileWarning(found, routerDir, target)); - }); - - it('looks for the file with the configured `pageExtensions`', () => { - const warnSpy = setUp(['src/app/page.page.tsx', 'instrumentation.page.ts']); - - warnIfMisplacedInstrumentationFile({ pageExtensions: ['page.tsx', 'page.ts'] }, {}); + warnIfMissingInstrumentationFile({}, {}); expect(warnSpy).toHaveBeenCalledTimes(1); - expect(warnSpy).toHaveBeenCalledWith( - misplacedFileWarning('instrumentation.page.ts', 'src/app', 'src/instrumentation.page.ts'), - ); + expect(warnSpy).toHaveBeenCalledWith(missingFileWarning(routerDir, target)); }); it('warns only once', () => { const warnSpy = setUp(ROOT_FILE_WITH_SRC_APP); - warnIfMisplacedInstrumentationFile({}, {}); - warnIfMisplacedInstrumentationFile({}, {}); + warnIfMissingInstrumentationFile({}, {}); + warnIfMissingInstrumentationFile({}, {}); expect(warnSpy).toHaveBeenCalledTimes(1); }); it.each([ ['the file is next to `src/app`', ['src/app/page.tsx', 'src/instrumentation.ts']], - ['the file is next to `app`', ['app/page.tsx', 'instrumentation.ts']], + ['the file is next to `app`', ['app/page.tsx', 'instrumentation.js']], ['a file is in both folders', ['src/app/page.tsx', 'src/instrumentation.ts', 'instrumentation.ts']], - [ - 'a root `pages` directory takes precedence over `src/app`', - ['pages/index.tsx', 'src/app/page.tsx', 'instrumentation.ts'], - ], - ['the project has no `app` or `pages` directory', ['instrumentation.ts']], + ['the project has no `app` or `pages` directory', []], ])('does not warn when %s', (_setup, files) => { const warnSpy = setUp(files); - warnIfMisplacedInstrumentationFile({}, {}); + warnIfMissingInstrumentationFile({}, {}); + + expect(warnSpy).not.toHaveBeenCalled(); + }); + + it('looks for the file with the configured `pageExtensions`', () => { + const warnSpy = setUp(['src/app/page.page.tsx', 'src/instrumentation.page.ts']); + + warnIfMissingInstrumentationFile({ pageExtensions: ['page.tsx', 'page.ts'] }, {}); expect(warnSpy).not.toHaveBeenCalled(); }); @@ -209,7 +198,7 @@ describe('warnIfMisplacedInstrumentationFile', () => { it('does not warn with `silent`', () => { const warnSpy = setUp(ROOT_FILE_WITH_SRC_APP); - warnIfMisplacedInstrumentationFile({}, { silent: true }); + warnIfMissingInstrumentationFile({}, { silent: true }); expect(warnSpy).not.toHaveBeenCalled(); }); @@ -218,7 +207,7 @@ describe('warnIfMisplacedInstrumentationFile', () => { vi.stubEnv('SENTRY_SUPPRESS_INSTRUMENTATION_FILE_WARNING', '1'); const warnSpy = setUp(ROOT_FILE_WITH_SRC_APP); - warnIfMisplacedInstrumentationFile({}, {}); + warnIfMissingInstrumentationFile({}, {}); expect(warnSpy).not.toHaveBeenCalled(); });