From dfe051390b48e56a4375e9dae27a598eb4ccf078 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Tue, 12 Sep 2023 07:21:26 +0000 Subject: [PATCH 1/2] fix(nextjs): Add new potential location for Next.js request AsyncLocalStorage --- .../app/route-handlers/[param]/edge/route.ts | 2 +- .../app/route-handlers/[param]/error/route.ts | 2 +- .../src/config/loaders/wrappingLoader.ts | 34 +++++++++++++------ 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/packages/e2e-tests/test-applications/nextjs-app-dir/app/route-handlers/[param]/edge/route.ts b/packages/e2e-tests/test-applications/nextjs-app-dir/app/route-handlers/[param]/edge/route.ts index 8c96a39e5554..a43862231568 100644 --- a/packages/e2e-tests/test-applications/nextjs-app-dir/app/route-handlers/[param]/edge/route.ts +++ b/packages/e2e-tests/test-applications/nextjs-app-dir/app/route-handlers/[param]/edge/route.ts @@ -6,6 +6,6 @@ export async function PATCH() { return NextResponse.json({ name: 'John Doe' }, { status: 401 }); } -export async function DELETE() { +export async function DELETE(): Promise { throw new Error('route-handler-edge-error'); } diff --git a/packages/e2e-tests/test-applications/nextjs-app-dir/app/route-handlers/[param]/error/route.ts b/packages/e2e-tests/test-applications/nextjs-app-dir/app/route-handlers/[param]/error/route.ts index fd50ef5c8a44..e2de561c4783 100644 --- a/packages/e2e-tests/test-applications/nextjs-app-dir/app/route-handlers/[param]/error/route.ts +++ b/packages/e2e-tests/test-applications/nextjs-app-dir/app/route-handlers/[param]/error/route.ts @@ -1,3 +1,3 @@ -export async function PUT() { +export async function PUT(): Promise { throw new Error('route-handler-error'); } diff --git a/packages/nextjs/src/config/loaders/wrappingLoader.ts b/packages/nextjs/src/config/loaders/wrappingLoader.ts index e6452f815184..dd5a92ef34ac 100644 --- a/packages/nextjs/src/config/loaders/wrappingLoader.ts +++ b/packages/nextjs/src/config/loaders/wrappingLoader.ts @@ -15,8 +15,8 @@ const SENTRY_WRAPPER_MODULE_NAME = 'sentry-wrapper-module'; // Needs to end in .cjs in order for the `commonjs` plugin to pick it up const WRAPPING_TARGET_MODULE_NAME = '__SENTRY_WRAPPING_TARGET_FILE__.cjs'; -// Non-public API. Can be found here: https://github.com/vercel/next.js/blob/46151dd68b417e7850146d00354f89930d10b43b/packages/next/src/client/components/request-async-storage.ts -const NEXTJS_REQUEST_ASYNC_STORAGE_MODULE_PATH = 'next/dist/client/components/request-async-storage'; +// This module is non-public API and may break +const nextjsRequestAsyncStorageModulePath = getAsyncLocalStorageModule(); const apiWrapperTemplatePath = path.resolve(__dirname, '..', 'templates', 'apiWrapperTemplate.js'); const apiWrapperTemplateCode = fs.readFileSync(apiWrapperTemplatePath, { encoding: 'utf8' }); @@ -27,7 +27,6 @@ const pageWrapperTemplateCode = fs.readFileSync(pageWrapperTemplatePath, { encod const middlewareWrapperTemplatePath = path.resolve(__dirname, '..', 'templates', 'middlewareWrapperTemplate.js'); const middlewareWrapperTemplateCode = fs.readFileSync(middlewareWrapperTemplatePath, { encoding: 'utf8' }); -const requestAsyncStorageModuleExists = moduleExists(NEXTJS_REQUEST_ASYNC_STORAGE_MODULE_PATH); let showedMissingAsyncStorageModuleWarning = false; const sentryInitWrapperTemplatePath = path.resolve(__dirname, '..', 'templates', 'sentryInitWrapperTemplate.js'); @@ -54,13 +53,28 @@ type LoaderOptions = { vercelCronsConfig?: VercelCronsConfig; }; -function moduleExists(id: string): boolean { +function getAsyncLocalStorageModule(): string | undefined { try { - require.resolve(id); - return true; - } catch (e) { - return false; + // Original location of that module + // https://github.com/vercel/next.js/blob/46151dd68b417e7850146d00354f89930d10b43b/packages/next/src/client/components/request-async-storage.ts + const location = 'next/dist/client/components/request-async-storage'; + require.resolve(location); + return location; + } catch { + // noop } + + try { + // Introduced in Next.js 13.4.20 + // https://github.com/vercel/next.js/blob/e1bc270830f2fc2df3542d4ef4c61b916c802df3/packages/next/src/client/components/request-async-storage.external.ts + const location = 'next/dist/client/components/request-async-storage.external'; + require.resolve(location); + return location; + } catch { + // noop + } + + return undefined; } /** @@ -183,10 +197,10 @@ export default function wrappingLoader( templateCode = routeHandlerWrapperTemplateCode; } - if (requestAsyncStorageModuleExists) { + if (nextjsRequestAsyncStorageModulePath !== undefined) { templateCode = templateCode.replace( /__SENTRY_NEXTJS_REQUEST_ASYNC_STORAGE_SHIM__/g, - NEXTJS_REQUEST_ASYNC_STORAGE_MODULE_PATH, + nextjsRequestAsyncStorageModulePath, ); } else { if (!showedMissingAsyncStorageModuleWarning) { From e27c44c7f0ec00e4f5fafaefb329236c569f7704 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Tue, 12 Sep 2023 07:25:32 +0000 Subject: [PATCH 2/2] rename --- packages/nextjs/src/config/loaders/wrappingLoader.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nextjs/src/config/loaders/wrappingLoader.ts b/packages/nextjs/src/config/loaders/wrappingLoader.ts index dd5a92ef34ac..ebeb6c90294b 100644 --- a/packages/nextjs/src/config/loaders/wrappingLoader.ts +++ b/packages/nextjs/src/config/loaders/wrappingLoader.ts @@ -16,7 +16,7 @@ const SENTRY_WRAPPER_MODULE_NAME = 'sentry-wrapper-module'; const WRAPPING_TARGET_MODULE_NAME = '__SENTRY_WRAPPING_TARGET_FILE__.cjs'; // This module is non-public API and may break -const nextjsRequestAsyncStorageModulePath = getAsyncLocalStorageModule(); +const nextjsRequestAsyncStorageModulePath = getRequestAsyncLocalStorageModule(); const apiWrapperTemplatePath = path.resolve(__dirname, '..', 'templates', 'apiWrapperTemplate.js'); const apiWrapperTemplateCode = fs.readFileSync(apiWrapperTemplatePath, { encoding: 'utf8' }); @@ -53,7 +53,7 @@ type LoaderOptions = { vercelCronsConfig?: VercelCronsConfig; }; -function getAsyncLocalStorageModule(): string | undefined { +function getRequestAsyncLocalStorageModule(): string | undefined { try { // Original location of that module // https://github.com/vercel/next.js/blob/46151dd68b417e7850146d00354f89930d10b43b/packages/next/src/client/components/request-async-storage.ts