Skip to content

Commit 7e7e5f2

Browse files
fix(nextjs): Disable server instrumentation on Vercel (#4255)
On Vercel, the server instrumentation has no effect. Errors and transactions are captured through the [custom `_error.js` page](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#create-a-custom-_error-page) and the [`withSentry` handler](https://docs.sentry.io/platforms/javascript/guides/nextjs/#configure). Not instrumenting the server (to not import any modules from `next`) when an app is deployed on Vercel should fix the issue.
1 parent 24b600f commit 7e7e5f2

File tree

2 files changed

+37
-16
lines changed

2 files changed

+37
-16
lines changed

packages/nextjs/src/index.server.ts

+33-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { escapeStringForRegex, logger } from '@sentry/utils';
66
import * as domainModule from 'domain';
77
import * as path from 'path';
88

9-
import { instrumentServer } from './utils/instrumentServer';
109
import { MetadataBuilder } from './utils/metadataBuilder';
1110
import { NextjsOptions } from './utils/nextjsOptions';
1211
import { addIntegration } from './utils/userIntegrations';
@@ -20,6 +19,17 @@ export { ErrorBoundary, withErrorBoundary } from '@sentry/react';
2019
type GlobalWithDistDir = typeof global & { __rewriteFramesDistDir__: string };
2120
const domain = domainModule as typeof domainModule & { active: (domainModule.Domain & Carrier) | null };
2221

22+
// During build, the main process is invoked by
23+
// `node next build`
24+
// and child processes are invoked as
25+
// `node <path>/node_modules/jest-worker/build/workers/processChild.js`,
26+
// whereas at runtime the process is invoked as
27+
// `node next start`
28+
// or
29+
// `node /var/runtime/index.js`.
30+
const isBuild = new RegExp('build').test(process.argv.toString());
31+
const isVercel = !!process.env.VERCEL;
32+
2333
/** Inits the Sentry NextJS SDK on node. */
2434
export function init(options: NextjsOptions): void {
2535
if (options.debug) {
@@ -54,7 +64,7 @@ export function init(options: NextjsOptions): void {
5464

5565
configureScope(scope => {
5666
scope.setTag('runtime', 'node');
57-
if (process.env.VERCEL) {
67+
if (isVercel) {
5868
scope.setTag('vercel', true);
5969
}
6070

@@ -119,5 +129,24 @@ function filterTransactions(event: Event): Event | null {
119129
export { withSentryConfig } from './config';
120130
export { withSentry } from './utils/withSentry';
121131

122-
// wrap various server methods to enable error monitoring and tracing
123-
instrumentServer();
132+
// Wrap various server methods to enable error monitoring and tracing. (Note: This only happens for non-Vercel
133+
// deployments, because the current method of doing the wrapping a) crashes Next 12 apps deployed to Vercel and
134+
// b) doesn't work on those apps anyway. We also don't do it during build, because there's no server running in that
135+
// phase.)
136+
if (!isVercel && !isBuild) {
137+
// Dynamically require the file because even importing from it causes Next 12 to crash on Vercel.
138+
// In environments where the JS file doesn't exist, such as testing, import the TS file.
139+
try {
140+
// eslint-disable-next-line @typescript-eslint/no-var-requires
141+
const { instrumentServer } = require('./utils/instrumentServer.js');
142+
instrumentServer();
143+
} catch {
144+
try {
145+
// eslint-disable-next-line @typescript-eslint/no-var-requires
146+
const { instrumentServer } = require('./utils/instrumentServer.ts');
147+
instrumentServer();
148+
} catch {
149+
// Server not instrumented. Not adding logs to avoid noise.
150+
}
151+
}
152+
}

packages/nextjs/test/index.server.test.ts

+4-12
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ describe('Server init()', () => {
2424
afterEach(() => {
2525
jest.clearAllMocks();
2626
global.__SENTRY__.hub = undefined;
27+
delete process.env.VERCEL;
2728
});
2829

2930
it('inits the Node SDK', () => {
@@ -66,18 +67,9 @@ describe('Server init()', () => {
6667
expect(currentScope._tags).toEqual({ runtime: 'node' });
6768
});
6869

69-
it('applies `vercel` tag when running on vercel', () => {
70-
const currentScope = getCurrentHub().getScope();
71-
72-
process.env.VERCEL = '1';
73-
74-
init({});
75-
76-
// @ts-ignore need access to protected _tags attribute
77-
expect(currentScope._tags.vercel).toEqual(true);
78-
79-
delete process.env.VERCEL;
80-
});
70+
// TODO: test `vercel` tag when running on Vercel
71+
// Can't just add the test and set env variables, since the value in `index.server.ts`
72+
// is resolved when importing.
8173

8274
it('does not apply `vercel` tag when not running on vercel', () => {
8375
const currentScope = getCurrentHub().getScope();

0 commit comments

Comments
 (0)