From 04a795b707370dc35b78f1b01271b3683199460d Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Fri, 2 Dec 2022 10:54:43 +0000 Subject: [PATCH 1/4] feat(nextjs): Don't init SDK on Vercel Edge Runtime --- packages/nextjs/src/index.server.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/nextjs/src/index.server.ts b/packages/nextjs/src/index.server.ts index e64349b89c4f..993abbd4cdb8 100644 --- a/packages/nextjs/src/index.server.ts +++ b/packages/nextjs/src/index.server.ts @@ -22,6 +22,11 @@ export { ErrorBoundary, showReportDialog, withErrorBoundary } from '@sentry/reac type GlobalWithDistDir = typeof global & { __rewriteFramesDistDir__: string }; const domain = domainModule as typeof domainModule & { active: (domainModule.Domain & Carrier) | null }; +// This is a variable that Next.js will string replace during build with a string if run in an edge runtime from Next.js +// v12.2.1-canary.3 onwards: +// https://github.com/vercel/next.js/blob/166e5fb9b92f64c4b5d1f6560a05e2b9778c16fb/packages/next/build/webpack-config.ts#L206 +declare const EdgeRuntime: string | undefined; + // Exporting this constant means we can compute it without the linter complaining, even if we stop directly using it in // this file. It's important that it be computed as early as possible, because one of its indicators is seeing 'build' // (as in the CLI command `next build`) in `process.argv`. Later on in the build process, everything's been spun out @@ -37,6 +42,11 @@ export function init(options: NextjsOptions): void { logger.enable(); } + if (typeof EdgeRuntime === 'string') { + __DEBUG_BUILD__ && logger.log('Vercel Edge Runtime detected. Will not initialize SDK.'); + return; + } + __DEBUG_BUILD__ && logger.log('Initializing SDK...'); if (sdkAlreadyInitialized()) { From 95282f3a68b038c15e4dab91e8be7c475f0b54d1 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Mon, 5 Dec 2022 09:48:08 +0000 Subject: [PATCH 2/4] Skip init in client side sdk --- packages/nextjs/src/index.client.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/nextjs/src/index.client.ts b/packages/nextjs/src/index.client.ts index d4054b264436..b2e89647b8bc 100644 --- a/packages/nextjs/src/index.client.ts +++ b/packages/nextjs/src/index.client.ts @@ -28,8 +28,20 @@ export { BrowserTracing }; // Treeshakable guard to remove all code related to tracing declare const __SENTRY_TRACING__: boolean; +// This is a variable that Next.js will string replace during build with a string if run in an edge runtime from Next.js +// v12.2.1-canary.3 onwards: +// https://github.com/vercel/next.js/blob/166e5fb9b92f64c4b5d1f6560a05e2b9778c16fb/packages/next/build/webpack-config.ts#L206 +declare const EdgeRuntime: string | undefined; + /** Inits the Sentry NextJS SDK on the browser with the React SDK. */ export function init(options: NextjsOptions): void { + if (typeof EdgeRuntime === 'string') { + // If the SDK is imported when using the Vercel Edge Runtime, it will import the browser SDK, even though it is + // running the server part of a Next.js application. We can use the `EdgeRuntime` to check for that case and make + // the init call a no-op. This will prevent the SDK from crashing on the Edge Runtime. + return; + } + buildMetadata(options, ['nextjs', 'react']); options.environment = options.environment || process.env.NODE_ENV; From 0ef59bc6faa0542bba9e17c9e017a992e0bc35d2 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Mon, 5 Dec 2022 09:48:21 +0000 Subject: [PATCH 3/4] Don't wrap api if edge runtime --- .../src/config/templates/apiProxyLoaderTemplate.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/nextjs/src/config/templates/apiProxyLoaderTemplate.ts b/packages/nextjs/src/config/templates/apiProxyLoaderTemplate.ts index 1cd7c40181eb..6aa0782f1233 100644 --- a/packages/nextjs/src/config/templates/apiProxyLoaderTemplate.ts +++ b/packages/nextjs/src/config/templates/apiProxyLoaderTemplate.ts @@ -23,7 +23,7 @@ type NextApiModule = ( } // CJS export | NextApiHandler -) & { config?: PageConfig }; +) & { config?: PageConfig & { runtime?: string } }; const userApiModule = origModule as NextApiModule; @@ -53,7 +53,13 @@ export const config = { }, }; -export default userProvidedHandler ? Sentry.withSentryAPI(userProvidedHandler, '__ROUTE__') : undefined; +const isEdgeRuntime = origConfig.runtime === 'experimental-edge'; + +export default userProvidedHandler + ? isEdgeRuntime + ? userProvidedHandler + : Sentry.withSentryAPI(userProvidedHandler, '__ROUTE__') + : undefined; // Re-export anything exported by the page module we're wrapping. When processing this code, Rollup is smart enough to // not include anything whose name matchs something we've explicitly exported above. From 2c7e9290c9469e7706994a0c435b736766e151a1 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Mon, 5 Dec 2022 10:24:59 +0000 Subject: [PATCH 4/4] Add log in client sdk --- packages/nextjs/src/index.client.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/nextjs/src/index.client.ts b/packages/nextjs/src/index.client.ts index db1f020cc50d..a28969824c92 100644 --- a/packages/nextjs/src/index.client.ts +++ b/packages/nextjs/src/index.client.ts @@ -2,6 +2,7 @@ import { RewriteFrames } from '@sentry/integrations'; import { configureScope, init as reactInit, Integrations } from '@sentry/react'; import { BrowserTracing, defaultRequestInstrumentationOptions, hasTracingEnabled } from '@sentry/tracing'; import { EventProcessor } from '@sentry/types'; +import { logger } from '@sentry/utils'; import { nextRouterInstrumentation } from './performance/client'; import { buildMetadata } from './utils/metadata'; @@ -42,6 +43,7 @@ export function init(options: NextjsOptions): void { // If the SDK is imported when using the Vercel Edge Runtime, it will import the browser SDK, even though it is // running the server part of a Next.js application. We can use the `EdgeRuntime` to check for that case and make // the init call a no-op. This will prevent the SDK from crashing on the Edge Runtime. + __DEBUG_BUILD__ && logger.log('Vercel Edge Runtime detected. Will not initialize SDK.'); return; }