Skip to content

Commit e46451e

Browse files
fix(nextjs): Use correct abs path for server init (#3649)
This fixes a bug caused by next build being run on a different machine than next start. Because we've been setting the env var SENTRY_SERVER_INIT_PATH (which we do during build) as an absolute, rather than relative, path, changing machines has made that path invalid when it's later used during server startup. This switches to using a relative path, so that it will work regardless of the machine on which it's run. Separately, it also fixes a bug where the path (absolute or relative) to the server init file was incorrect when using webpack 5. Under webpack 5, the path in the webpack config's output.path variable points to a different location (one directory deeper) than in webpack 4. To compensate for that difference, the config (as created by next) has a different output.filename value (one including ../ at the beginning), so that then combination points to the same spot as under webpack 4. This PR takes advantage of that by including filename in it derivation of the server init file's final location. Closes #3648 Co-authored-by: Abhijeet Prasad <[email protected]> Co-authored-by: Katie Byers <[email protected]>
1 parent 7e7b291 commit e46451e

File tree

3 files changed

+19
-11
lines changed

3 files changed

+19
-11
lines changed

packages/nextjs/package.json

+5-4
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,11 @@
5555
"test": "run-s test:unit test:integration",
5656
"test:watch": "jest --watch",
5757
"test:unit": "jest",
58-
"test:integration": "run-s test:integration:build test:integration:server test:integration:client",
59-
"test:integration:build": "cd test/integration && yarn && yarn build && cd ../..",
60-
"test:integration:server": "node test/integration/test/server.js --silent",
61-
"test:integration:client": "node test/integration/test/client.js --silent",
58+
"test:integration": "run-s test:integration:clean test:integration:build test:integration:server test:integration:client",
59+
"test:integration:clean": "cd test/integration && rimraf node_modules .next .env.local",
60+
"test:integration:build": "cd test/integration && yarn && yarn build",
61+
"test:integration:server": "cd test/integration && node test/server.js --silent",
62+
"test:integration:client": "cd test/integration && node test/client.js --silent",
6263
"pack": "npm pack",
6364
"vercel:branch": "source vercel/set-up-branch-for-test-app-use.sh",
6465
"vercel:project": "source vercel/make-project-use-current-branch.sh"

packages/nextjs/src/utils/config.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import * as path from 'path';
77

88
const SENTRY_CLIENT_CONFIG_FILE = './sentry.client.config.js';
99
const SENTRY_SERVER_CONFIG_FILE = './sentry.server.config.js';
10-
// this is where the transpiled/bundled version of `USER_SERVER_CONFIG_FILE` will end up
10+
// this is where the transpiled/bundled version of `SENTRY_SERVER_CONFIG_FILE` will end up
1111
export const SERVER_SDK_INIT_PATH = 'sentry/initServerSDK.js';
1212

1313
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -21,7 +21,7 @@ type WebpackConfig = {
2121
devtool: string;
2222
plugins: PlainObject[];
2323
entry: EntryProperty;
24-
output: { path: string };
24+
output: { filename: string; path: string };
2525
target: string;
2626
context: string;
2727
};
@@ -156,9 +156,13 @@ export function withSentryConfig(
156156
// if we're building server code, store the webpack output path as an env variable, so we know where to look for the
157157
// webpack-processed version of `sentry.server.config.js` when we need it
158158
if (config.target === 'node') {
159-
const serverSDKInitOutputPath = path.join(config.output.path, SERVER_SDK_INIT_PATH);
159+
const outputLocation = path.dirname(path.join(config.output.path, config.output.filename));
160+
const serverSDKInitOutputPath = path.join(outputLocation, SERVER_SDK_INIT_PATH);
160161
const projectDir = config.context;
161-
setRuntimeEnvVars(projectDir, { SENTRY_SERVER_INIT_PATH: serverSDKInitOutputPath });
162+
setRuntimeEnvVars(projectDir, {
163+
// ex: .next/server/sentry/initServerSdk.js
164+
SENTRY_SERVER_INIT_PATH: path.relative(projectDir, serverSDKInitOutputPath),
165+
});
162166
}
163167

164168
let newConfig = config;

packages/nextjs/src/utils/instrumentServer.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { fill, isString, logger, stripUrlQueryAndFragment } from '@sentry/utils'
55
import * as domain from 'domain';
66
import * as http from 'http';
77
import { default as createNextServer } from 'next';
8+
import * as path from 'path';
89
import * as querystring from 'querystring';
910
import * as url from 'url';
1011

@@ -114,11 +115,13 @@ function makeWrappedHandlerGetter(origHandlerGetter: HandlerGetter): WrappedHand
114115
try {
115116
// `SENTRY_SERVER_INIT_PATH` is set at build time, and points to a webpack-processed version of the user's
116117
// `sentry.server.config.js`. Requiring it starts the SDK.
117-
require(process.env.SENTRY_SERVER_INIT_PATH as string);
118+
require(path.resolve(process.env.SENTRY_SERVER_INIT_PATH as string));
118119
} catch (err) {
119120
// Log the error but don't bail - we still want the wrapping to happen, in case the user is doing something weird
120-
// and manually calling `Sentry.init()` somewhere else.
121-
logger.error(`[Sentry] Could not initialize SDK. Received error:\n${err}`);
121+
// and manually calling `Sentry.init()` somewhere else. We log to console instead of using logger from utils
122+
// because Sentry is not initialized.
123+
// eslint-disable-next-line no-console
124+
console.error(`[Sentry] Could not initialize SDK. Received error:\n${err}`);
122125
}
123126

124127
// stash this in the closure so that `makeWrappedReqHandler` can use it

0 commit comments

Comments
 (0)