From b6d33670721d945a6742726c522d21acc223335a Mon Sep 17 00:00:00 2001 From: Abdellah Hariti Date: Tue, 25 Feb 2025 13:33:06 +0000 Subject: [PATCH 1/5] fix(nextjs/instrumentation): warn about missing onRequestError handler closes #15049 --- packages/nextjs/src/config/webpack.ts | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index 5ff02da355a1..528147e930a4 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -56,6 +56,7 @@ export function constructWebpackConfigFunction( if (runtime !== 'client') { warnAboutDeprecatedConfigFiles(projectDir, runtime); + warnAboutMissingonRequestErrorHandler(projectDir); } let rawNewConfig = { ...incomingConfig }; @@ -435,6 +436,33 @@ async function addSentryToClientEntryProperty( return newEntryProperty; } +/** + * Make sure the instrumentation file has a `onRequestError` Handler + * + * @param projectDir The root directory of the project, where config files would be located + */ +function warnAboutMissingonRequestErrorHandler(projectDir: string): void { + const instrumentationPaths = [ + ['src', 'instrumentation.ts'], + ['src', 'instrumentation.js'], + ['instrumentation.ts'], + ['instrumentation.js'], + ]; + function hasOnRequestErrorHandler(pathSegments: string[]): boolean { + const filePath = path.resolve(projectDir, ...pathSegments); + try { + const content = fs.readFileSync(filePath, 'utf8'); + return content.includes('export const onRequestError'); + } catch (error) { + return false; + } + } + if (!instrumentationPaths.some(hasOnRequestErrorHandler)) { + // eslint-disable-next-line no-console + console.warn(`${chalk.yellow('[@sentry/nextjs]')} Missing 'onRequestError' handler in instrumentation file.`); + } +} + /** * Searches for old `sentry.(server|edge).config.ts` files and Next.js instrumentation hooks and warns if there are "old" * config files and no signs of them inside the instrumentation hook. From df67430a3d8ee934f6e95ffe502e8be99e935a8d Mon Sep 17 00:00:00 2001 From: abdellah hariti Date: Tue, 25 Feb 2025 14:23:10 +0000 Subject: [PATCH 2/5] better warning message Co-authored-by: Luca Forstner --- packages/nextjs/src/config/webpack.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index 528147e930a4..060e018d3fbb 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -459,7 +459,7 @@ function warnAboutMissingonRequestErrorHandler(projectDir: string): void { } if (!instrumentationPaths.some(hasOnRequestErrorHandler)) { // eslint-disable-next-line no-console - console.warn(`${chalk.yellow('[@sentry/nextjs]')} Missing 'onRequestError' handler in instrumentation file.`); + console.warn(`${chalk.yellow('[@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`); } } From 572a5d7db1a49008fa6f623b752a1f5ac872b09a Mon Sep 17 00:00:00 2001 From: Abdellah Hariti Date: Tue, 25 Feb 2025 14:39:44 +0000 Subject: [PATCH 3/5] warn about missing instrumentation file and only warn about missing onRequestError when an instrumentation file exists --- packages/nextjs/src/config/webpack.ts | 34 +++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index 060e018d3fbb..1e6983599ab6 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -448,18 +448,42 @@ function warnAboutMissingonRequestErrorHandler(projectDir: string): void { ['instrumentation.ts'], ['instrumentation.js'], ]; - function hasOnRequestErrorHandler(pathSegments: string[]): boolean { - const filePath = path.resolve(projectDir, ...pathSegments); + const instrumentationFile = instrumentationPaths + .map(pathSegments => path.resolve(projectDir, ...pathSegments)) + .find(function exists(filePath: string): string | null { + try { + fs.accessSync(filePath, fs.constants.F_OK); + return filePath; + } catch (error) { + return null; + } + }); + + function hasOnRequestErrorHandler(absolutePath: string): boolean { try { - const content = fs.readFileSync(filePath, 'utf8'); + const content = fs.readFileSync(absolutePath, 'utf8'); return content.includes('export const onRequestError'); } catch (error) { return false; } } - if (!instrumentationPaths.some(hasOnRequestErrorHandler)) { + + if (!instrumentationFile) { + // eslint-disable-next-line no-console + return console.warn( + `${chalk.yellow( + '[@sentry/nextjs]', + )} Could not find instrumentation file: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#create-initialization-config-files`, + ); + } + + if (!hasOnRequestErrorHandler(instrumentationFile)) { // eslint-disable-next-line no-console - console.warn(`${chalk.yellow('[@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`); + console.warn( + `${chalk.yellow( + '[@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`, + ); } } From 4758a9d3823dcf03e05cc5d8e5b9ee3111c2667f Mon Sep 17 00:00:00 2001 From: Abdellah Hariti Date: Tue, 25 Feb 2025 14:49:19 +0000 Subject: [PATCH 4/5] review items --- packages/nextjs/src/config/webpack.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index 1e6983599ab6..64c164154c37 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -56,6 +56,8 @@ export function constructWebpackConfigFunction( if (runtime !== 'client') { warnAboutDeprecatedConfigFiles(projectDir, runtime); + } + if (runtime === 'server') { warnAboutMissingonRequestErrorHandler(projectDir); } @@ -462,7 +464,7 @@ function warnAboutMissingonRequestErrorHandler(projectDir: string): void { function hasOnRequestErrorHandler(absolutePath: string): boolean { try { const content = fs.readFileSync(absolutePath, 'utf8'); - return content.includes('export const onRequestError'); + return content.includes('onRequestError'); } catch (error) { return false; } From a37b66da0f6b4e8e25ae97547e1e9c775e840a2e Mon Sep 17 00:00:00 2001 From: abdellah hariti Date: Tue, 25 Feb 2025 15:23:48 +0000 Subject: [PATCH 5/5] better warning message Co-authored-by: Luca Forstner --- packages/nextjs/src/config/webpack.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index 64c164154c37..6c691424f115 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -475,7 +475,7 @@ function warnAboutMissingonRequestErrorHandler(projectDir: string): void { return console.warn( `${chalk.yellow( '[@sentry/nextjs]', - )} Could not find instrumentation file: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#create-initialization-config-files`, + )} 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`, ); }