@sentry/wizard 1.2.15 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +12 -6
- package/dist/Electron/symbols.js +5 -16
- package/dist/NextJs/configs/_error.js +30 -52
- package/dist/lib/Steps/Integrations/NextJs.d.ts +1 -1
- package/dist/lib/Steps/Integrations/NextJs.js +16 -12
- package/dist/lib/Steps/Integrations/NextJs.js.map +1 -1
- package/lib/Steps/Integrations/NextJs.ts +36 -11
- package/package.json +2 -2
- package/scripts/Electron/symbols.js +5 -16
- package/scripts/NextJs/configs/_error.js +30 -52
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 1.3.0
|
|
6
|
+
|
|
7
|
+
- chore(deps): Bump sentry-cli to 1.72.0 (#154)
|
|
8
|
+
- feat(nextjs): Use helper function in `_error.js` (#170)
|
|
9
|
+
- fix(electron): Fix version detection to use electron/package.json (#161)
|
|
10
|
+
|
|
11
|
+
## 1.2.17
|
|
12
|
+
|
|
13
|
+
- Support Next.js v12 (#152)
|
|
14
|
+
|
|
15
|
+
## 1.2.16
|
|
16
|
+
|
|
17
|
+
- fix(nextjs): Do not capture 404s as exceptions in `_error` (#146)
|
|
18
|
+
|
|
5
19
|
## 1.2.15
|
|
6
20
|
|
|
7
21
|
- Check version range rather than minimum version for nextjs (#143)
|
package/README.md
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
<
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
<a href="https://sentry.io/?utm_source=github&utm_medium=logo" target="_blank">
|
|
3
|
+
<picture>
|
|
4
|
+
<source srcset="https://sentry-brand.storage.googleapis.com/sentry-logo-white.png" media="(prefers-color-scheme: dark)" />
|
|
5
|
+
<source srcset="https://sentry-brand.storage.googleapis.com/sentry-logo-black.png" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" />
|
|
6
|
+
<img src="https://sentry-brand.storage.googleapis.com/sentry-logo-black.png" alt="Sentry" width="280">
|
|
7
|
+
</picture>
|
|
8
|
+
</a>
|
|
8
9
|
</p>
|
|
9
10
|
|
|
11
|
+
<h1>Sentry Wizard</h1>
|
|
12
|
+
<h4>The Sentry Wizard helps you set up your React Native, Cordova, Electron or Next.js projects with Sentry.</h4>
|
|
13
|
+
|
|
10
14
|
[](https://www.npmjs.com/package/@sentry/wizard)
|
|
11
15
|
[](https://www.npmjs.com/package/@sentry/wizard)
|
|
12
16
|
[](https://www.npmjs.com/package/@sentry/wizard)
|
|
@@ -45,6 +49,8 @@ yarn sentry-wizard
|
|
|
45
49
|
npx @sentry/wizard
|
|
46
50
|
```
|
|
47
51
|
|
|
52
|
+
At the current moment, the wizard is meant to be used for React Native, Cordova, Electron or Next.js. If you have other platforms you would like the wizard to support, please open a [GitHub issue](https://github.com/getsentry/sentry-wizard/issues)!
|
|
53
|
+
|
|
48
54
|
# Options
|
|
49
55
|
|
|
50
56
|
```
|
package/dist/Electron/symbols.js
CHANGED
|
@@ -12,15 +12,13 @@ try {
|
|
|
12
12
|
process.exit(1);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
const VERSION = /\bv?(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[\da-z-]+(?:\.[\da-z-]+)*)?(?:\+[\da-z-]+(?:\.[\da-z-]+)*)?\b/i;
|
|
16
15
|
const SYMBOL_CACHE_FOLDER = '.electron-symbols';
|
|
17
|
-
const package = require('./package.json');
|
|
18
16
|
const sentryCli = new SentryCli('./sentry.properties');
|
|
19
17
|
|
|
20
18
|
async function main() {
|
|
21
19
|
let version = getElectronVersion();
|
|
22
20
|
if (!version) {
|
|
23
|
-
console.error('Cannot detect electron version, check
|
|
21
|
+
console.error('Cannot detect electron version, check that electron is installed');
|
|
24
22
|
return;
|
|
25
23
|
}
|
|
26
24
|
|
|
@@ -68,20 +66,11 @@ async function main() {
|
|
|
68
66
|
}
|
|
69
67
|
|
|
70
68
|
function getElectronVersion() {
|
|
71
|
-
|
|
72
|
-
return
|
|
69
|
+
try {
|
|
70
|
+
return require('electron/package.json').version;
|
|
71
|
+
} catch (error) {
|
|
72
|
+
return undefined;
|
|
73
73
|
}
|
|
74
|
-
|
|
75
|
-
let electronVersion =
|
|
76
|
-
(package.dependencies && package.dependencies.electron) ||
|
|
77
|
-
(package.devDependencies && package.devDependencies.electron);
|
|
78
|
-
|
|
79
|
-
if (!electronVersion) {
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const matches = VERSION.exec(electronVersion);
|
|
84
|
-
return matches ? matches[0] : false;
|
|
85
74
|
}
|
|
86
75
|
|
|
87
76
|
async function downloadSymbols(options) {
|
|
@@ -1,61 +1,39 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* NOTE: This requires `@sentry/nextjs` version 7.3.0 or higher.
|
|
3
|
+
*
|
|
4
|
+
* NOTE: If using this with `next` version 12.2.0 or lower, uncomment the
|
|
5
|
+
* penultimate line in `CustomErrorComponent`.
|
|
6
|
+
*
|
|
7
|
+
* This page is loaded by Nextjs:
|
|
8
|
+
* - on the server, when data-fetching methods throw or reject
|
|
9
|
+
* - on the client, when `getInitialProps` throws or rejects
|
|
10
|
+
* - on the client, when a React lifecycle method throws or rejects, and it's
|
|
11
|
+
* caught by the built-in Nextjs error boundary
|
|
12
|
+
*
|
|
13
|
+
* See:
|
|
14
|
+
* - https://nextjs.org/docs/basic-features/data-fetching/overview
|
|
15
|
+
* - https://nextjs.org/docs/api-reference/data-fetching/get-initial-props
|
|
16
|
+
* - https://reactjs.org/docs/error-boundaries.html
|
|
17
|
+
*/
|
|
2
18
|
|
|
3
19
|
import * as Sentry from '@sentry/nextjs';
|
|
20
|
+
import NextErrorComponent from 'next/error';
|
|
4
21
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
// err via _app.js so it can be captured
|
|
10
|
-
Sentry.captureException(err);
|
|
11
|
-
// Flushing is not required in this case as it only happens on the client
|
|
12
|
-
}
|
|
22
|
+
const CustomErrorComponent = props => {
|
|
23
|
+
// If you're using a Nextjs version prior to 12.2.1, uncomment this to
|
|
24
|
+
// compensate for https://github.com/vercel/next.js/issues/8592
|
|
25
|
+
// Sentry.captureUnderscoreErrorException(props);
|
|
13
26
|
|
|
14
|
-
return <NextErrorComponent statusCode={statusCode} />;
|
|
27
|
+
return <NextErrorComponent statusCode={props.statusCode} />;
|
|
15
28
|
};
|
|
16
29
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
// Workaround for https://github.com/vercel/next.js/issues/8592, mark when
|
|
24
|
-
// getInitialProps has run
|
|
25
|
-
errorInitialProps.hasGetInitialPropsRun = true;
|
|
26
|
-
|
|
27
|
-
// Running on the server, the response object (`res`) is available.
|
|
28
|
-
//
|
|
29
|
-
// Next.js will pass an err on the server if a page's data fetching methods
|
|
30
|
-
// threw or returned a Promise that rejected
|
|
31
|
-
//
|
|
32
|
-
// Running on the client (browser), Next.js will provide an err if:
|
|
33
|
-
//
|
|
34
|
-
// - a page's `getInitialProps` threw or returned a Promise that rejected
|
|
35
|
-
// - an exception was thrown somewhere in the React lifecycle (render,
|
|
36
|
-
// componentDidMount, etc) that was caught by Next.js's React Error
|
|
37
|
-
// Boundary. Read more about what types of exceptions are caught by Error
|
|
38
|
-
// Boundaries: https://reactjs.org/docs/error-boundaries.html
|
|
39
|
-
|
|
40
|
-
if (err) {
|
|
41
|
-
Sentry.captureException(err);
|
|
42
|
-
|
|
43
|
-
// Flushing before returning is necessary if deploying to Vercel, see
|
|
44
|
-
// https://vercel.com/docs/platform/limits#streaming-responses
|
|
45
|
-
await Sentry.flush(2000);
|
|
46
|
-
|
|
47
|
-
return errorInitialProps;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// If this point is reached, getInitialProps was called without any
|
|
51
|
-
// information about what the error might be. This is unexpected and may
|
|
52
|
-
// indicate a bug introduced in Next.js, so record it in Sentry
|
|
53
|
-
Sentry.captureException(
|
|
54
|
-
new Error(`_error.js getInitialProps missing data at path: ${asPath}`),
|
|
55
|
-
);
|
|
56
|
-
await Sentry.flush(2000);
|
|
30
|
+
CustomErrorComponent.getInitialProps = async contextData => {
|
|
31
|
+
// In case this is running in a serverless function, await this in order to give Sentry
|
|
32
|
+
// time to send the error before the lambda exits
|
|
33
|
+
await Sentry.captureUnderscoreErrorException(contextData);
|
|
57
34
|
|
|
58
|
-
|
|
35
|
+
// This will contain the status code of the response
|
|
36
|
+
return NextErrorComponent.getInitialProps(contextData);
|
|
59
37
|
};
|
|
60
38
|
|
|
61
|
-
export default
|
|
39
|
+
export default CustomErrorComponent;
|
|
@@ -13,7 +13,7 @@ export declare class NextJs extends BaseIntegration {
|
|
|
13
13
|
private _createNextConfig;
|
|
14
14
|
private _setTemplate;
|
|
15
15
|
private _fillAndCopyTemplate;
|
|
16
|
-
private
|
|
16
|
+
private _checkPackageVersion;
|
|
17
17
|
private _fulfillsVersionRange;
|
|
18
18
|
private _spliceInPlace;
|
|
19
19
|
}
|
|
@@ -77,7 +77,8 @@ var semver_1 = require("semver");
|
|
|
77
77
|
var Logging_1 = require("../../Helper/Logging");
|
|
78
78
|
var SentryCli_1 = require("../../Helper/SentryCli");
|
|
79
79
|
var BaseIntegration_1 = require("./BaseIntegration");
|
|
80
|
-
var COMPATIBLE_NEXTJS_VERSIONS = '>=10.0.8 <
|
|
80
|
+
var COMPATIBLE_NEXTJS_VERSIONS = '>=10.0.8 <13.0.0';
|
|
81
|
+
var COMPATIBLE_SDK_VERSIONS = '>=7.3.0';
|
|
81
82
|
var PROPERTIES_FILENAME = 'sentry.properties';
|
|
82
83
|
var SENTRYCLIRC_FILENAME = '.sentryclirc';
|
|
83
84
|
var GITIGNORE_FILENAME = '.gitignore';
|
|
@@ -144,7 +145,9 @@ var NextJs = /** @class */ (function (_super) {
|
|
|
144
145
|
}
|
|
145
146
|
Logging_1.nl();
|
|
146
147
|
userAnswers = { continue: true };
|
|
147
|
-
if (!(!this.
|
|
148
|
+
if (!((!this._checkPackageVersion('next', COMPATIBLE_NEXTJS_VERSIONS, true) ||
|
|
149
|
+
!this._checkPackageVersion('@sentry/nextjs', COMPATIBLE_SDK_VERSIONS, true)) &&
|
|
150
|
+
!this._argv.quiet)) return [3 /*break*/, 2];
|
|
148
151
|
return [4 /*yield*/, inquirer_1.prompt({
|
|
149
152
|
message: 'There were errors during your project checkup, do you still want to continue?',
|
|
150
153
|
name: 'continue',
|
|
@@ -286,7 +289,7 @@ var NextJs = /** @class */ (function (_super) {
|
|
|
286
289
|
var filledTemplate = templateContent.replace('___DSN___', dsn);
|
|
287
290
|
fs.writeFileSync(targetPath, filledTemplate);
|
|
288
291
|
};
|
|
289
|
-
NextJs.prototype.
|
|
292
|
+
NextJs.prototype._checkPackageVersion = function (packageName, acceptableVersions, canBeLatest) {
|
|
290
293
|
var depsVersion = _.get(appPackage, ['dependencies', packageName]);
|
|
291
294
|
var devDepsVersion = _.get(appPackage, ['devDependencies', packageName]);
|
|
292
295
|
if (!depsVersion && !devDepsVersion) {
|
|
@@ -294,9 +297,9 @@ var NextJs = /** @class */ (function (_super) {
|
|
|
294
297
|
Logging_1.red(' Please install it with yarn/npm.');
|
|
295
298
|
return false;
|
|
296
299
|
}
|
|
297
|
-
else if (!this._fulfillsVersionRange(depsVersion) &&
|
|
298
|
-
!this._fulfillsVersionRange(devDepsVersion)) {
|
|
299
|
-
Logging_1.red("\u2717 Your `package.json` specifies a version of `" + packageName + "` outside of the compatible version range " +
|
|
300
|
+
else if (!this._fulfillsVersionRange(depsVersion, acceptableVersions, canBeLatest) &&
|
|
301
|
+
!this._fulfillsVersionRange(devDepsVersion, acceptableVersions, canBeLatest)) {
|
|
302
|
+
Logging_1.red("\u2717 Your `package.json` specifies a version of `" + packageName + "` outside of the compatible version range " + acceptableVersions + ".\n");
|
|
300
303
|
return false;
|
|
301
304
|
}
|
|
302
305
|
else {
|
|
@@ -304,10 +307,9 @@ var NextJs = /** @class */ (function (_super) {
|
|
|
304
307
|
return true;
|
|
305
308
|
}
|
|
306
309
|
};
|
|
307
|
-
NextJs.prototype._fulfillsVersionRange = function (version) {
|
|
308
|
-
// The latest version is currently 12.x, which is not yet supported.
|
|
310
|
+
NextJs.prototype._fulfillsVersionRange = function (version, acceptableVersions, canBeLatest) {
|
|
309
311
|
if (version === 'latest') {
|
|
310
|
-
return
|
|
312
|
+
return canBeLatest;
|
|
311
313
|
}
|
|
312
314
|
var cleanedUserVersion, isRange;
|
|
313
315
|
if (semver_1.valid(version)) {
|
|
@@ -318,10 +320,12 @@ var NextJs = /** @class */ (function (_super) {
|
|
|
318
320
|
cleanedUserVersion = semver_1.validRange(version);
|
|
319
321
|
isRange = true;
|
|
320
322
|
}
|
|
321
|
-
return (
|
|
323
|
+
return (
|
|
324
|
+
// If the given version is a bogus format, this will still be undefined and we'll automatically reject it
|
|
325
|
+
!!cleanedUserVersion &&
|
|
322
326
|
(isRange
|
|
323
|
-
? semver_1.subset(cleanedUserVersion,
|
|
324
|
-
: semver_1.satisfies(cleanedUserVersion,
|
|
327
|
+
? semver_1.subset(cleanedUserVersion, acceptableVersions)
|
|
328
|
+
: semver_1.satisfies(cleanedUserVersion, acceptableVersions)));
|
|
325
329
|
};
|
|
326
330
|
NextJs.prototype._spliceInPlace = function (arr, start, deleteCount) {
|
|
327
331
|
var inserts = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NextJs.js","sourceRoot":"","sources":["../../../../lib/Steps/Integrations/NextJs.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\nimport * as fs from 'fs';\nimport { Answers, prompt } from 'inquirer';\nimport * as _ from 'lodash';\nimport * as path from 'path';\nimport { satisfies, subset, valid, validRange } from 'semver';\n\nimport { Args } from '../../Constants';\nimport { debug, green, l, nl, red } from '../../Helper/Logging';\nimport { SentryCli, SentryCliProps } from '../../Helper/SentryCli';\nimport { BaseIntegration } from './BaseIntegration';\n\nconst COMPATIBLE_NEXTJS_VERSIONS = '>=10.0.8 <12.0.0';\nconst PROPERTIES_FILENAME = 'sentry.properties';\nconst SENTRYCLIRC_FILENAME = '.sentryclirc';\nconst GITIGNORE_FILENAME = '.gitignore';\nconst CONFIG_DIR = 'configs/';\nconst MERGEABLE_CONFIG_INFIX = 'wizardcopy';\n\n// for those files which can go in more than one place, the list of places they\n// could go (the first one which works will be used)\nconst TEMPLATE_DESTINATIONS: { [key: string]: string[] } = {\n '_error.js': ['pages', 'src/pages'],\n 'next.config.js': ['.'],\n 'sentry.server.config.js': ['.'],\n 'sentry.client.config.js': ['.'],\n};\n\nlet appPackage: any = {};\n\ntry {\n appPackage = require(path.join(process.cwd(), 'package.json'));\n} catch {\n // We don't need to have this\n}\n\nexport class NextJs extends BaseIntegration {\n protected _sentryCli: SentryCli;\n\n constructor(protected _argv: Args) {\n super(_argv);\n this._sentryCli = new SentryCli(this._argv);\n }\n\n public async emit(answers: Answers): Promise<Answers> {\n const dsn = _.get(answers, ['config', 'dsn', 'public'], null);\n nl();\n\n const sentryCliProps = this._sentryCli.convertAnswersToProperties(answers);\n await this._createSentryCliConfig(sentryCliProps);\n\n const configDirectory = path.join(\n __dirname,\n '..',\n '..',\n '..',\n 'NextJs',\n CONFIG_DIR,\n );\n\n if (fs.existsSync(configDirectory)) {\n this._createNextConfig(configDirectory, dsn);\n } else {\n debug(\n `Couldn't find ${configDirectory}, probably because you ran this from inside of \\`/lib\\` rather than \\`/dist\\``,\n );\n nl();\n }\n\n l(\n 'For more information, see https://docs.sentry.io/platforms/javascript/guides/nextjs/',\n );\n nl();\n\n return {};\n }\n\n public async shouldConfigure(_answers: Answers): Promise<Answers> {\n if (this._shouldConfigure) {\n return this._shouldConfigure;\n }\n\n nl();\n\n let userAnswers: Answers = { continue: true };\n if (!this._checkUserNextVersion('next') && !this._argv.quiet) {\n userAnswers = await prompt({\n message:\n 'There were errors during your project checkup, do you still want to continue?',\n name: 'continue',\n default: false,\n type: 'confirm',\n });\n }\n\n nl();\n\n if (!userAnswers['continue']) {\n throw new Error('Please install the required dependencies to continue.');\n }\n\n this._shouldConfigure = Promise.resolve({ nextjs: true });\n // eslint-disable-next-line @typescript-eslint/unbound-method\n return this.shouldConfigure;\n }\n\n private async _createSentryCliConfig(\n cliProps: SentryCliProps,\n ): Promise<void> {\n const { 'auth/token': authToken, ...cliPropsToWrite } = cliProps;\n\n /**\n * To not commit the auth token to the VCS, instead of adding it to the\n * properties file (like the rest of props), it's added to the Sentry CLI\n * config, which is added to the gitignore. This way makes the properties\n * file safe to commit without exposing any auth tokens.\n */\n if (authToken) {\n try {\n await fs.promises.appendFile(\n SENTRYCLIRC_FILENAME,\n this._sentryCli.dumpConfig({ auth: { token: authToken } }),\n );\n green(`✓ Successfully added the auth token to ${SENTRYCLIRC_FILENAME}`);\n } catch {\n red(\n `⚠ Could not add the auth token to ${SENTRYCLIRC_FILENAME}, ` +\n `please add it to identify your user account:\\n${authToken}`,\n );\n nl();\n }\n } else {\n red(\n `⚠ Did not find an auth token, please add your token to ${SENTRYCLIRC_FILENAME}`,\n );\n l(\n 'To generate an auth token, visit https://sentry.io/settings/account/api/auth-tokens/',\n );\n l(\n 'To learn how to configure Sentry CLI, visit ' +\n 'https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli',\n );\n }\n\n await this._addToGitignore(\n SENTRYCLIRC_FILENAME,\n `⚠ Could not add ${SENTRYCLIRC_FILENAME} to ${GITIGNORE_FILENAME}, ` +\n 'please add it to not commit your auth key.',\n );\n\n try {\n await fs.promises.writeFile(\n `./${PROPERTIES_FILENAME}`,\n this._sentryCli.dumpProperties(cliPropsToWrite),\n );\n green(`✓ Successfully created sentry.properties`);\n } catch {\n red(`⚠ Could not add org and project data to ${PROPERTIES_FILENAME}`);\n l(\n 'See docs for a manual setup: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli',\n );\n }\n nl();\n }\n\n private async _addToGitignore(\n filepath: string,\n errorMsg: string,\n ): Promise<void> {\n /**\n * Don't check whether the given file is ignored because:\n * 1. It's tricky to check it without git.\n * 2. Git might not be installed or accessible.\n * 3. It's convenient to use a module to interact with git, but it would\n * increase the size x2 approximately. Docs say to run the Wizard without\n * installing it, and duplicating the size would slow the set-up down.\n * 4. The Wizard is meant to be run once.\n * 5. A message is logged informing users it's been added to the gitignore.\n * 6. It will be added to the gitignore as many times as it runs - not a big\n * deal.\n * 7. It's straightforward to remove it from the gitignore.\n */\n try {\n await fs.promises.appendFile(\n GITIGNORE_FILENAME,\n `\\n# Sentry\\n${filepath}\\n`,\n );\n green(`✓ ${filepath} added to ${GITIGNORE_FILENAME}`);\n } catch {\n red(errorMsg);\n }\n }\n\n private _createNextConfig(configDirectory: string, dsn: any): void {\n const templates = fs.readdirSync(configDirectory);\n for (const template of templates) {\n this._setTemplate(\n configDirectory,\n template,\n TEMPLATE_DESTINATIONS[template],\n dsn,\n );\n }\n red(\n '⚠ Performance monitoring is enabled capturing 100% of transactions.\\n' +\n ' Learn more in https://docs.sentry.io/product/performance/',\n );\n nl();\n }\n\n private _setTemplate(\n configDirectory: string,\n templateFile: string,\n destinationOptions: string[],\n dsn: string,\n ): void {\n const templatePath = path.join(configDirectory, templateFile);\n\n for (const destinationDir of destinationOptions) {\n if (!fs.existsSync(destinationDir)) {\n continue;\n }\n\n const destinationPath = path.join(destinationDir, templateFile);\n // in case the file in question already exists, we'll make a copy with\n // `MERGEABLE_CONFIG_INFIX` inserted just before the extension, so as not\n // to overwrite the existing file\n const mergeableFilePath = path.join(\n destinationDir,\n this._spliceInPlace(\n templateFile.split('.'),\n -1,\n 0,\n MERGEABLE_CONFIG_INFIX,\n ).join('.'),\n );\n\n if (!fs.existsSync(destinationPath)) {\n this._fillAndCopyTemplate(templatePath, destinationPath, dsn);\n } else if (!fs.existsSync(mergeableFilePath)) {\n this._fillAndCopyTemplate(templatePath, mergeableFilePath, dsn);\n red(\n `File \\`${templateFile}\\` already exists, so created \\`${mergeableFilePath}\\`.\\n` +\n 'Please merge those files.',\n );\n nl();\n } else {\n red(\n `Both \\`${templateFile}\\` and \\`${mergeableFilePath}\\` already exist.\\n` +\n 'Please merge those files.',\n );\n nl();\n }\n return;\n }\n\n red(\n `Could not find appropriate destination for \\`${templateFile}\\`. Tried: ${destinationOptions}.`,\n );\n nl();\n }\n\n private _fillAndCopyTemplate(\n sourcePath: string,\n targetPath: string,\n dsn: string,\n ): void {\n const templateContent = fs.readFileSync(sourcePath).toString();\n const filledTemplate = templateContent.replace('___DSN___', dsn);\n fs.writeFileSync(targetPath, filledTemplate);\n }\n\n private _checkUserNextVersion(packageName: string): boolean {\n const depsVersion = _.get(appPackage, ['dependencies', packageName]);\n const devDepsVersion = _.get(appPackage, ['devDependencies', packageName]);\n\n if (!depsVersion && !devDepsVersion) {\n red(`✗ ${packageName} isn't in your dependencies.`);\n red(' Please install it with yarn/npm.');\n return false;\n } else if (\n !this._fulfillsVersionRange(depsVersion) &&\n !this._fulfillsVersionRange(devDepsVersion)\n ) {\n red(\n `✗ Your \\`package.json\\` specifies a version of \\`${packageName}\\` outside of the compatible version range ${COMPATIBLE_NEXTJS_VERSIONS}.\\n`,\n );\n return false;\n } else {\n green(\n `✓ A compatible version of \\`${packageName}\\` is specified in \\`package.json\\`.`,\n );\n return true;\n }\n }\n\n private _fulfillsVersionRange(version: string): boolean {\n // The latest version is currently 12.x, which is not yet supported.\n if (version === 'latest') {\n return false;\n }\n\n let cleanedUserVersion, isRange;\n\n if (valid(version)) {\n cleanedUserVersion = valid(version);\n isRange = false;\n } else if (validRange(version)) {\n cleanedUserVersion = validRange(version);\n isRange = true;\n }\n\n return (\n !!cleanedUserVersion &&\n (isRange\n ? subset(cleanedUserVersion, COMPATIBLE_NEXTJS_VERSIONS)\n : satisfies(cleanedUserVersion, COMPATIBLE_NEXTJS_VERSIONS))\n );\n }\n\n private _spliceInPlace(\n arr: Array<any>,\n start: number,\n deleteCount: number,\n ...inserts: any[]\n ): Array<any> {\n arr.splice(start, deleteCount, ...inserts);\n return arr;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"NextJs.js","sourceRoot":"","sources":["../../../../lib/Steps/Integrations/NextJs.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\nimport * as fs from 'fs';\nimport { Answers, prompt } from 'inquirer';\nimport * as _ from 'lodash';\nimport * as path from 'path';\nimport { satisfies, subset, valid, validRange } from 'semver';\n\nimport { Args } from '../../Constants';\nimport { debug, green, l, nl, red } from '../../Helper/Logging';\nimport { SentryCli, SentryCliProps } from '../../Helper/SentryCli';\nimport { BaseIntegration } from './BaseIntegration';\n\nconst COMPATIBLE_NEXTJS_VERSIONS = '>=10.0.8 <13.0.0';\nconst COMPATIBLE_SDK_VERSIONS = '>=7.3.0';\nconst PROPERTIES_FILENAME = 'sentry.properties';\nconst SENTRYCLIRC_FILENAME = '.sentryclirc';\nconst GITIGNORE_FILENAME = '.gitignore';\nconst CONFIG_DIR = 'configs/';\nconst MERGEABLE_CONFIG_INFIX = 'wizardcopy';\n\n// for those files which can go in more than one place, the list of places they\n// could go (the first one which works will be used)\nconst TEMPLATE_DESTINATIONS: { [key: string]: string[] } = {\n '_error.js': ['pages', 'src/pages'],\n 'next.config.js': ['.'],\n 'sentry.server.config.js': ['.'],\n 'sentry.client.config.js': ['.'],\n};\n\nlet appPackage: any = {};\n\ntry {\n appPackage = require(path.join(process.cwd(), 'package.json'));\n} catch {\n // We don't need to have this\n}\n\nexport class NextJs extends BaseIntegration {\n protected _sentryCli: SentryCli;\n\n constructor(protected _argv: Args) {\n super(_argv);\n this._sentryCli = new SentryCli(this._argv);\n }\n\n public async emit(answers: Answers): Promise<Answers> {\n const dsn = _.get(answers, ['config', 'dsn', 'public'], null);\n nl();\n\n const sentryCliProps = this._sentryCli.convertAnswersToProperties(answers);\n await this._createSentryCliConfig(sentryCliProps);\n\n const configDirectory = path.join(\n __dirname,\n '..',\n '..',\n '..',\n 'NextJs',\n CONFIG_DIR,\n );\n\n if (fs.existsSync(configDirectory)) {\n this._createNextConfig(configDirectory, dsn);\n } else {\n debug(\n `Couldn't find ${configDirectory}, probably because you ran this from inside of \\`/lib\\` rather than \\`/dist\\``,\n );\n nl();\n }\n\n l(\n 'For more information, see https://docs.sentry.io/platforms/javascript/guides/nextjs/',\n );\n nl();\n\n return {};\n }\n\n public async shouldConfigure(_answers: Answers): Promise<Answers> {\n if (this._shouldConfigure) {\n return this._shouldConfigure;\n }\n\n nl();\n\n let userAnswers: Answers = { continue: true };\n if (\n (!this._checkPackageVersion('next', COMPATIBLE_NEXTJS_VERSIONS, true) ||\n !this._checkPackageVersion(\n '@sentry/nextjs',\n COMPATIBLE_SDK_VERSIONS,\n true,\n )) &&\n !this._argv.quiet\n ) {\n userAnswers = await prompt({\n message:\n 'There were errors during your project checkup, do you still want to continue?',\n name: 'continue',\n default: false,\n type: 'confirm',\n });\n }\n\n nl();\n\n if (!userAnswers['continue']) {\n throw new Error('Please install the required dependencies to continue.');\n }\n\n this._shouldConfigure = Promise.resolve({ nextjs: true });\n // eslint-disable-next-line @typescript-eslint/unbound-method\n return this.shouldConfigure;\n }\n\n private async _createSentryCliConfig(\n cliProps: SentryCliProps,\n ): Promise<void> {\n const { 'auth/token': authToken, ...cliPropsToWrite } = cliProps;\n\n /**\n * To not commit the auth token to the VCS, instead of adding it to the\n * properties file (like the rest of props), it's added to the Sentry CLI\n * config, which is added to the gitignore. This way makes the properties\n * file safe to commit without exposing any auth tokens.\n */\n if (authToken) {\n try {\n await fs.promises.appendFile(\n SENTRYCLIRC_FILENAME,\n this._sentryCli.dumpConfig({ auth: { token: authToken } }),\n );\n green(`✓ Successfully added the auth token to ${SENTRYCLIRC_FILENAME}`);\n } catch {\n red(\n `⚠ Could not add the auth token to ${SENTRYCLIRC_FILENAME}, ` +\n `please add it to identify your user account:\\n${authToken}`,\n );\n nl();\n }\n } else {\n red(\n `⚠ Did not find an auth token, please add your token to ${SENTRYCLIRC_FILENAME}`,\n );\n l(\n 'To generate an auth token, visit https://sentry.io/settings/account/api/auth-tokens/',\n );\n l(\n 'To learn how to configure Sentry CLI, visit ' +\n 'https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli',\n );\n }\n\n await this._addToGitignore(\n SENTRYCLIRC_FILENAME,\n `⚠ Could not add ${SENTRYCLIRC_FILENAME} to ${GITIGNORE_FILENAME}, ` +\n 'please add it to not commit your auth key.',\n );\n\n try {\n await fs.promises.writeFile(\n `./${PROPERTIES_FILENAME}`,\n this._sentryCli.dumpProperties(cliPropsToWrite),\n );\n green(`✓ Successfully created sentry.properties`);\n } catch {\n red(`⚠ Could not add org and project data to ${PROPERTIES_FILENAME}`);\n l(\n 'See docs for a manual setup: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli',\n );\n }\n nl();\n }\n\n private async _addToGitignore(\n filepath: string,\n errorMsg: string,\n ): Promise<void> {\n /**\n * Don't check whether the given file is ignored because:\n * 1. It's tricky to check it without git.\n * 2. Git might not be installed or accessible.\n * 3. It's convenient to use a module to interact with git, but it would\n * increase the size x2 approximately. Docs say to run the Wizard without\n * installing it, and duplicating the size would slow the set-up down.\n * 4. The Wizard is meant to be run once.\n * 5. A message is logged informing users it's been added to the gitignore.\n * 6. It will be added to the gitignore as many times as it runs - not a big\n * deal.\n * 7. It's straightforward to remove it from the gitignore.\n */\n try {\n await fs.promises.appendFile(\n GITIGNORE_FILENAME,\n `\\n# Sentry\\n${filepath}\\n`,\n );\n green(`✓ ${filepath} added to ${GITIGNORE_FILENAME}`);\n } catch {\n red(errorMsg);\n }\n }\n\n private _createNextConfig(configDirectory: string, dsn: any): void {\n const templates = fs.readdirSync(configDirectory);\n for (const template of templates) {\n this._setTemplate(\n configDirectory,\n template,\n TEMPLATE_DESTINATIONS[template],\n dsn,\n );\n }\n red(\n '⚠ Performance monitoring is enabled capturing 100% of transactions.\\n' +\n ' Learn more in https://docs.sentry.io/product/performance/',\n );\n nl();\n }\n\n private _setTemplate(\n configDirectory: string,\n templateFile: string,\n destinationOptions: string[],\n dsn: string,\n ): void {\n const templatePath = path.join(configDirectory, templateFile);\n\n for (const destinationDir of destinationOptions) {\n if (!fs.existsSync(destinationDir)) {\n continue;\n }\n\n const destinationPath = path.join(destinationDir, templateFile);\n // in case the file in question already exists, we'll make a copy with\n // `MERGEABLE_CONFIG_INFIX` inserted just before the extension, so as not\n // to overwrite the existing file\n const mergeableFilePath = path.join(\n destinationDir,\n this._spliceInPlace(\n templateFile.split('.'),\n -1,\n 0,\n MERGEABLE_CONFIG_INFIX,\n ).join('.'),\n );\n\n if (!fs.existsSync(destinationPath)) {\n this._fillAndCopyTemplate(templatePath, destinationPath, dsn);\n } else if (!fs.existsSync(mergeableFilePath)) {\n this._fillAndCopyTemplate(templatePath, mergeableFilePath, dsn);\n red(\n `File \\`${templateFile}\\` already exists, so created \\`${mergeableFilePath}\\`.\\n` +\n 'Please merge those files.',\n );\n nl();\n } else {\n red(\n `Both \\`${templateFile}\\` and \\`${mergeableFilePath}\\` already exist.\\n` +\n 'Please merge those files.',\n );\n nl();\n }\n return;\n }\n\n red(\n `Could not find appropriate destination for \\`${templateFile}\\`. Tried: ${destinationOptions}.`,\n );\n nl();\n }\n\n private _fillAndCopyTemplate(\n sourcePath: string,\n targetPath: string,\n dsn: string,\n ): void {\n const templateContent = fs.readFileSync(sourcePath).toString();\n const filledTemplate = templateContent.replace('___DSN___', dsn);\n fs.writeFileSync(targetPath, filledTemplate);\n }\n\n private _checkPackageVersion(\n packageName: string,\n acceptableVersions: string,\n canBeLatest: boolean,\n ): boolean {\n const depsVersion = _.get(appPackage, ['dependencies', packageName]);\n const devDepsVersion = _.get(appPackage, ['devDependencies', packageName]);\n\n if (!depsVersion && !devDepsVersion) {\n red(`✗ ${packageName} isn't in your dependencies.`);\n red(' Please install it with yarn/npm.');\n return false;\n } else if (\n !this._fulfillsVersionRange(\n depsVersion,\n acceptableVersions,\n canBeLatest,\n ) &&\n !this._fulfillsVersionRange(\n devDepsVersion,\n acceptableVersions,\n canBeLatest,\n )\n ) {\n red(\n `✗ Your \\`package.json\\` specifies a version of \\`${packageName}\\` outside of the compatible version range ${acceptableVersions}.\\n`,\n );\n return false;\n } else {\n green(\n `✓ A compatible version of \\`${packageName}\\` is specified in \\`package.json\\`.`,\n );\n return true;\n }\n }\n\n private _fulfillsVersionRange(\n version: string,\n acceptableVersions: string,\n canBeLatest: boolean,\n ): boolean {\n if (version === 'latest') {\n return canBeLatest;\n }\n\n let cleanedUserVersion, isRange;\n\n if (valid(version)) {\n cleanedUserVersion = valid(version);\n isRange = false;\n } else if (validRange(version)) {\n cleanedUserVersion = validRange(version);\n isRange = true;\n }\n\n return (\n // If the given version is a bogus format, this will still be undefined and we'll automatically reject it\n !!cleanedUserVersion &&\n (isRange\n ? subset(cleanedUserVersion, acceptableVersions)\n : satisfies(cleanedUserVersion, acceptableVersions))\n );\n }\n\n private _spliceInPlace(\n arr: Array<any>,\n start: number,\n deleteCount: number,\n ...inserts: any[]\n ): Array<any> {\n arr.splice(start, deleteCount, ...inserts);\n return arr;\n }\n}\n"]}
|
|
@@ -10,7 +10,8 @@ import { debug, green, l, nl, red } from '../../Helper/Logging';
|
|
|
10
10
|
import { SentryCli, SentryCliProps } from '../../Helper/SentryCli';
|
|
11
11
|
import { BaseIntegration } from './BaseIntegration';
|
|
12
12
|
|
|
13
|
-
const COMPATIBLE_NEXTJS_VERSIONS = '>=10.0.8 <
|
|
13
|
+
const COMPATIBLE_NEXTJS_VERSIONS = '>=10.0.8 <13.0.0';
|
|
14
|
+
const COMPATIBLE_SDK_VERSIONS = '>=7.3.0';
|
|
14
15
|
const PROPERTIES_FILENAME = 'sentry.properties';
|
|
15
16
|
const SENTRYCLIRC_FILENAME = '.sentryclirc';
|
|
16
17
|
const GITIGNORE_FILENAME = '.gitignore';
|
|
@@ -83,7 +84,15 @@ export class NextJs extends BaseIntegration {
|
|
|
83
84
|
nl();
|
|
84
85
|
|
|
85
86
|
let userAnswers: Answers = { continue: true };
|
|
86
|
-
if (
|
|
87
|
+
if (
|
|
88
|
+
(!this._checkPackageVersion('next', COMPATIBLE_NEXTJS_VERSIONS, true) ||
|
|
89
|
+
!this._checkPackageVersion(
|
|
90
|
+
'@sentry/nextjs',
|
|
91
|
+
COMPATIBLE_SDK_VERSIONS,
|
|
92
|
+
true,
|
|
93
|
+
)) &&
|
|
94
|
+
!this._argv.quiet
|
|
95
|
+
) {
|
|
87
96
|
userAnswers = await prompt({
|
|
88
97
|
message:
|
|
89
98
|
'There were errors during your project checkup, do you still want to continue?',
|
|
@@ -270,7 +279,11 @@ export class NextJs extends BaseIntegration {
|
|
|
270
279
|
fs.writeFileSync(targetPath, filledTemplate);
|
|
271
280
|
}
|
|
272
281
|
|
|
273
|
-
private
|
|
282
|
+
private _checkPackageVersion(
|
|
283
|
+
packageName: string,
|
|
284
|
+
acceptableVersions: string,
|
|
285
|
+
canBeLatest: boolean,
|
|
286
|
+
): boolean {
|
|
274
287
|
const depsVersion = _.get(appPackage, ['dependencies', packageName]);
|
|
275
288
|
const devDepsVersion = _.get(appPackage, ['devDependencies', packageName]);
|
|
276
289
|
|
|
@@ -279,11 +292,19 @@ export class NextJs extends BaseIntegration {
|
|
|
279
292
|
red(' Please install it with yarn/npm.');
|
|
280
293
|
return false;
|
|
281
294
|
} else if (
|
|
282
|
-
!this._fulfillsVersionRange(
|
|
283
|
-
|
|
295
|
+
!this._fulfillsVersionRange(
|
|
296
|
+
depsVersion,
|
|
297
|
+
acceptableVersions,
|
|
298
|
+
canBeLatest,
|
|
299
|
+
) &&
|
|
300
|
+
!this._fulfillsVersionRange(
|
|
301
|
+
devDepsVersion,
|
|
302
|
+
acceptableVersions,
|
|
303
|
+
canBeLatest,
|
|
304
|
+
)
|
|
284
305
|
) {
|
|
285
306
|
red(
|
|
286
|
-
`✗ Your \`package.json\` specifies a version of \`${packageName}\` outside of the compatible version range ${
|
|
307
|
+
`✗ Your \`package.json\` specifies a version of \`${packageName}\` outside of the compatible version range ${acceptableVersions}.\n`,
|
|
287
308
|
);
|
|
288
309
|
return false;
|
|
289
310
|
} else {
|
|
@@ -294,10 +315,13 @@ export class NextJs extends BaseIntegration {
|
|
|
294
315
|
}
|
|
295
316
|
}
|
|
296
317
|
|
|
297
|
-
private _fulfillsVersionRange(
|
|
298
|
-
|
|
318
|
+
private _fulfillsVersionRange(
|
|
319
|
+
version: string,
|
|
320
|
+
acceptableVersions: string,
|
|
321
|
+
canBeLatest: boolean,
|
|
322
|
+
): boolean {
|
|
299
323
|
if (version === 'latest') {
|
|
300
|
-
return
|
|
324
|
+
return canBeLatest;
|
|
301
325
|
}
|
|
302
326
|
|
|
303
327
|
let cleanedUserVersion, isRange;
|
|
@@ -311,10 +335,11 @@ export class NextJs extends BaseIntegration {
|
|
|
311
335
|
}
|
|
312
336
|
|
|
313
337
|
return (
|
|
338
|
+
// If the given version is a bogus format, this will still be undefined and we'll automatically reject it
|
|
314
339
|
!!cleanedUserVersion &&
|
|
315
340
|
(isRange
|
|
316
|
-
? subset(cleanedUserVersion,
|
|
317
|
-
: satisfies(cleanedUserVersion,
|
|
341
|
+
? subset(cleanedUserVersion, acceptableVersions)
|
|
342
|
+
: satisfies(cleanedUserVersion, acceptableVersions))
|
|
318
343
|
);
|
|
319
344
|
}
|
|
320
345
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/wizard",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"homepage": "https://github.com/getsentry/sentry-wizard",
|
|
5
5
|
"repository": "https://github.com/getsentry/sentry-wizard",
|
|
6
6
|
"description": "Sentry wizard helping you to configure your project",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"definition": "dist/index.d.ts"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@sentry/cli": "^1.
|
|
26
|
+
"@sentry/cli": "^1.72.0",
|
|
27
27
|
"chalk": "^2.4.1",
|
|
28
28
|
"glob": "^7.1.3",
|
|
29
29
|
"inquirer": "^6.2.0",
|
|
@@ -12,15 +12,13 @@ try {
|
|
|
12
12
|
process.exit(1);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
const VERSION = /\bv?(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[\da-z-]+(?:\.[\da-z-]+)*)?(?:\+[\da-z-]+(?:\.[\da-z-]+)*)?\b/i;
|
|
16
15
|
const SYMBOL_CACHE_FOLDER = '.electron-symbols';
|
|
17
|
-
const package = require('./package.json');
|
|
18
16
|
const sentryCli = new SentryCli('./sentry.properties');
|
|
19
17
|
|
|
20
18
|
async function main() {
|
|
21
19
|
let version = getElectronVersion();
|
|
22
20
|
if (!version) {
|
|
23
|
-
console.error('Cannot detect electron version, check
|
|
21
|
+
console.error('Cannot detect electron version, check that electron is installed');
|
|
24
22
|
return;
|
|
25
23
|
}
|
|
26
24
|
|
|
@@ -68,20 +66,11 @@ async function main() {
|
|
|
68
66
|
}
|
|
69
67
|
|
|
70
68
|
function getElectronVersion() {
|
|
71
|
-
|
|
72
|
-
return
|
|
69
|
+
try {
|
|
70
|
+
return require('electron/package.json').version;
|
|
71
|
+
} catch (error) {
|
|
72
|
+
return undefined;
|
|
73
73
|
}
|
|
74
|
-
|
|
75
|
-
let electronVersion =
|
|
76
|
-
(package.dependencies && package.dependencies.electron) ||
|
|
77
|
-
(package.devDependencies && package.devDependencies.electron);
|
|
78
|
-
|
|
79
|
-
if (!electronVersion) {
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const matches = VERSION.exec(electronVersion);
|
|
84
|
-
return matches ? matches[0] : false;
|
|
85
74
|
}
|
|
86
75
|
|
|
87
76
|
async function downloadSymbols(options) {
|
|
@@ -1,61 +1,39 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* NOTE: This requires `@sentry/nextjs` version 7.3.0 or higher.
|
|
3
|
+
*
|
|
4
|
+
* NOTE: If using this with `next` version 12.2.0 or lower, uncomment the
|
|
5
|
+
* penultimate line in `CustomErrorComponent`.
|
|
6
|
+
*
|
|
7
|
+
* This page is loaded by Nextjs:
|
|
8
|
+
* - on the server, when data-fetching methods throw or reject
|
|
9
|
+
* - on the client, when `getInitialProps` throws or rejects
|
|
10
|
+
* - on the client, when a React lifecycle method throws or rejects, and it's
|
|
11
|
+
* caught by the built-in Nextjs error boundary
|
|
12
|
+
*
|
|
13
|
+
* See:
|
|
14
|
+
* - https://nextjs.org/docs/basic-features/data-fetching/overview
|
|
15
|
+
* - https://nextjs.org/docs/api-reference/data-fetching/get-initial-props
|
|
16
|
+
* - https://reactjs.org/docs/error-boundaries.html
|
|
17
|
+
*/
|
|
2
18
|
|
|
3
19
|
import * as Sentry from '@sentry/nextjs';
|
|
20
|
+
import NextErrorComponent from 'next/error';
|
|
4
21
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
// err via _app.js so it can be captured
|
|
10
|
-
Sentry.captureException(err);
|
|
11
|
-
// Flushing is not required in this case as it only happens on the client
|
|
12
|
-
}
|
|
22
|
+
const CustomErrorComponent = props => {
|
|
23
|
+
// If you're using a Nextjs version prior to 12.2.1, uncomment this to
|
|
24
|
+
// compensate for https://github.com/vercel/next.js/issues/8592
|
|
25
|
+
// Sentry.captureUnderscoreErrorException(props);
|
|
13
26
|
|
|
14
|
-
return <NextErrorComponent statusCode={statusCode} />;
|
|
27
|
+
return <NextErrorComponent statusCode={props.statusCode} />;
|
|
15
28
|
};
|
|
16
29
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
// Workaround for https://github.com/vercel/next.js/issues/8592, mark when
|
|
24
|
-
// getInitialProps has run
|
|
25
|
-
errorInitialProps.hasGetInitialPropsRun = true;
|
|
26
|
-
|
|
27
|
-
// Running on the server, the response object (`res`) is available.
|
|
28
|
-
//
|
|
29
|
-
// Next.js will pass an err on the server if a page's data fetching methods
|
|
30
|
-
// threw or returned a Promise that rejected
|
|
31
|
-
//
|
|
32
|
-
// Running on the client (browser), Next.js will provide an err if:
|
|
33
|
-
//
|
|
34
|
-
// - a page's `getInitialProps` threw or returned a Promise that rejected
|
|
35
|
-
// - an exception was thrown somewhere in the React lifecycle (render,
|
|
36
|
-
// componentDidMount, etc) that was caught by Next.js's React Error
|
|
37
|
-
// Boundary. Read more about what types of exceptions are caught by Error
|
|
38
|
-
// Boundaries: https://reactjs.org/docs/error-boundaries.html
|
|
39
|
-
|
|
40
|
-
if (err) {
|
|
41
|
-
Sentry.captureException(err);
|
|
42
|
-
|
|
43
|
-
// Flushing before returning is necessary if deploying to Vercel, see
|
|
44
|
-
// https://vercel.com/docs/platform/limits#streaming-responses
|
|
45
|
-
await Sentry.flush(2000);
|
|
46
|
-
|
|
47
|
-
return errorInitialProps;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// If this point is reached, getInitialProps was called without any
|
|
51
|
-
// information about what the error might be. This is unexpected and may
|
|
52
|
-
// indicate a bug introduced in Next.js, so record it in Sentry
|
|
53
|
-
Sentry.captureException(
|
|
54
|
-
new Error(`_error.js getInitialProps missing data at path: ${asPath}`),
|
|
55
|
-
);
|
|
56
|
-
await Sentry.flush(2000);
|
|
30
|
+
CustomErrorComponent.getInitialProps = async contextData => {
|
|
31
|
+
// In case this is running in a serverless function, await this in order to give Sentry
|
|
32
|
+
// time to send the error before the lambda exits
|
|
33
|
+
await Sentry.captureUnderscoreErrorException(contextData);
|
|
57
34
|
|
|
58
|
-
|
|
35
|
+
// This will contain the status code of the response
|
|
36
|
+
return NextErrorComponent.getInitialProps(contextData);
|
|
59
37
|
};
|
|
60
38
|
|
|
61
|
-
export default
|
|
39
|
+
export default CustomErrorComponent;
|