From b6d33670721d945a6742726c522d21acc223335a Mon Sep 17 00:00:00 2001
From: Abdellah Hariti <haritiabdellah@gmail.com>
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 <haritiabdellah@gmail.com>
Date: Tue, 25 Feb 2025 14:23:10 +0000
Subject: [PATCH 2/5] better warning message

Co-authored-by: Luca Forstner <luca.forstner@sentry.io>
---
 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 <haritiabdellah@gmail.com>
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 <haritiabdellah@gmail.com>
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 <haritiabdellah@gmail.com>
Date: Tue, 25 Feb 2025 15:23:48 +0000
Subject: [PATCH 5/5] better warning message

Co-authored-by: Luca Forstner <luca.forstner@sentry.io>
---
 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`,
     );
   }