From b80df176e5ca6fd979a56151e25d46a0d581dcb0 Mon Sep 17 00:00:00 2001 From: Lukasz Ostrowski Date: Mon, 20 Mar 2023 10:25:36 +0100 Subject: [PATCH] CMS: Add Sentry setup (#311) --- .changeset/cuddly-cats-hang.md | 5 ++ apps/cms/next.config.js | 15 ++++ apps/cms/package.json | 1 + apps/cms/sentry.client.config.js | 17 ++++ apps/cms/sentry.edge.config.js | 17 ++++ apps/cms/sentry.server.config.js | 17 ++++ apps/cms/src/pages/_error.js | 39 +++++++++ pnpm-lock.yaml | 136 +++++++++++++++++++++++++++++++ 8 files changed, 247 insertions(+) create mode 100644 .changeset/cuddly-cats-hang.md create mode 100644 apps/cms/sentry.client.config.js create mode 100644 apps/cms/sentry.edge.config.js create mode 100644 apps/cms/sentry.server.config.js create mode 100644 apps/cms/src/pages/_error.js diff --git a/.changeset/cuddly-cats-hang.md b/.changeset/cuddly-cats-hang.md new file mode 100644 index 0000000..ade928b --- /dev/null +++ b/.changeset/cuddly-cats-hang.md @@ -0,0 +1,5 @@ +--- +"saleor-app-cms": minor +--- + +Added Sentry integration diff --git a/apps/cms/next.config.js b/apps/cms/next.config.js index 3dd7ef1..58c02e3 100644 --- a/apps/cms/next.config.js +++ b/apps/cms/next.config.js @@ -1,4 +1,19 @@ +// This file sets a custom webpack configuration to use your Next.js app +// with Sentry. +// https://nextjs.org/docs/api-reference/next.config.js/introduction +// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/ +const { withSentryConfig } = require("@sentry/nextjs"); + +const isSentryPropertiesInEnvironment = + process.env.SENTRY_AUTH_TOKEN && process.env.SENTRY_PROJECT && process.env.SENTRY_ORG; + /** @type {import('next').NextConfig} */ module.exports = { reactStrictMode: true, + sentry: { + disableServerWebpackPlugin: !isSentryPropertiesInEnvironment, + disableClientWebpackPlugin: !isSentryPropertiesInEnvironment, + }, }; + +module.exports = withSentryConfig(module.exports, { silent: true }, { hideSourcemaps: true }); diff --git a/apps/cms/package.json b/apps/cms/package.json index 5e46fed..1ebd582 100644 --- a/apps/cms/package.json +++ b/apps/cms/package.json @@ -22,6 +22,7 @@ "@material-ui/lab": "4.0.0-alpha.61", "@saleor/app-sdk": "0.37.1", "@saleor/macaw-ui": "^0.6.7", + "@sentry/nextjs": "^7.43.0", "@urql/exchange-auth": "^1.0.0", "clsx": "^1.2.1", "graphql": "^16.6.0", diff --git a/apps/cms/sentry.client.config.js b/apps/cms/sentry.client.config.js new file mode 100644 index 0000000..d480b2d --- /dev/null +++ b/apps/cms/sentry.client.config.js @@ -0,0 +1,17 @@ +// This file configures the initialization of Sentry on the browser. +// The config you add here will be used whenever a page is visited. +// https://docs.sentry.io/platforms/javascript/guides/nextjs/ + +import * as Sentry from "@sentry/nextjs"; + +const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN; + +Sentry.init({ + dsn: SENTRY_DSN, + // Adjust this value in production, or use tracesSampler for greater control + tracesSampleRate: 1.0, + // ... + // Note: if you want to override the automatic release value, do not set a + // `release` value here - use the environment variable `SENTRY_RELEASE`, so + // that it will also get attached to your source maps +}); diff --git a/apps/cms/sentry.edge.config.js b/apps/cms/sentry.edge.config.js new file mode 100644 index 0000000..1c3e861 --- /dev/null +++ b/apps/cms/sentry.edge.config.js @@ -0,0 +1,17 @@ +// This file configures the initialization of Sentry on the server. +// The config you add here will be used whenever middleware or an Edge route handles a request. +// https://docs.sentry.io/platforms/javascript/guides/nextjs/ + +import * as Sentry from "@sentry/nextjs"; + +const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN; + +Sentry.init({ + dsn: SENTRY_DSN, + // Adjust this value in production, or use tracesSampler for greater control + tracesSampleRate: 1.0, + // ... + // Note: if you want to override the automatic release value, do not set a + // `release` value here - use the environment variable `SENTRY_RELEASE`, so + // that it will also get attached to your source maps +}); diff --git a/apps/cms/sentry.server.config.js b/apps/cms/sentry.server.config.js new file mode 100644 index 0000000..a7e581b --- /dev/null +++ b/apps/cms/sentry.server.config.js @@ -0,0 +1,17 @@ +// This file configures the initialization of Sentry on the server. +// The config you add here will be used whenever the server handles a request. +// https://docs.sentry.io/platforms/javascript/guides/nextjs/ + +import * as Sentry from "@sentry/nextjs"; + +const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN; + +Sentry.init({ + dsn: SENTRY_DSN, + // Adjust this value in production, or use tracesSampler for greater control + tracesSampleRate: 1.0, + // ... + // Note: if you want to override the automatic release value, do not set a + // `release` value here - use the environment variable `SENTRY_RELEASE`, so + // that it will also get attached to your source maps +}); diff --git a/apps/cms/src/pages/_error.js b/apps/cms/src/pages/_error.js new file mode 100644 index 0000000..55c3486 --- /dev/null +++ b/apps/cms/src/pages/_error.js @@ -0,0 +1,39 @@ +/** + * NOTE: This requires `@sentry/nextjs` version 7.3.0 or higher. + * + * NOTE: If using this with `next` version 12.2.0 or lower, uncomment the + * penultimate line in `CustomErrorComponent`. + * + * This page is loaded by Nextjs: + * - on the server, when data-fetching methods throw or reject + * - on the client, when `getInitialProps` throws or rejects + * - on the client, when a React lifecycle method throws or rejects, and it's + * caught by the built-in Nextjs error boundary + * + * See: + * - https://nextjs.org/docs/basic-features/data-fetching/overview + * - https://nextjs.org/docs/api-reference/data-fetching/get-initial-props + * - https://reactjs.org/docs/error-boundaries.html + */ + +import * as Sentry from "@sentry/nextjs"; +import NextErrorComponent from "next/error"; + +const CustomErrorComponent = (props) => { + // If you're using a Nextjs version prior to 12.2.1, uncomment this to + // compensate for https://github.com/vercel/next.js/issues/8592 + // Sentry.captureUnderscoreErrorException(props); + + return ; +}; + +CustomErrorComponent.getInitialProps = async (contextData) => { + // In case this is running in a serverless function, await this in order to give Sentry + // time to send the error before the lambda exits + await Sentry.captureUnderscoreErrorException(contextData); + + // This will contain the status code of the response + return NextErrorComponent.getInitialProps(contextData); +}; + +export default CustomErrorComponent; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1d784ea..9ff3187 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -39,6 +39,7 @@ importers: '@material-ui/lab': 4.0.0-alpha.61 '@saleor/app-sdk': 0.37.1 '@saleor/macaw-ui': ^0.6.7 + '@sentry/nextjs': ^7.43.0 '@testing-library/react': ^13.4.0 '@types/node': ^18.8.1 '@types/react': ^18.0.21 @@ -74,6 +75,7 @@ importers: '@material-ui/lab': 4.0.0-alpha.61_x54wk6dsnsxe7g7vvfmytp77te '@saleor/app-sdk': 0.37.1_ld2jel3hspngo3u5lti2kgl2sq '@saleor/macaw-ui': 0.6.7_pmlnlm755hlzzzocw2qhf3a34e + '@sentry/nextjs': 7.43.0_next@13.2.4+react@18.2.0 '@urql/exchange-auth': 1.0.0_graphql@16.6.0 clsx: 1.2.1 graphql: 16.6.0 @@ -4903,6 +4905,17 @@ packages: tslib: 1.14.1 dev: false + /@sentry/browser/7.43.0: + resolution: {integrity: sha512-NlRkBYKb9o5IQdGY8Ktps19Hz9RdSuqS1tlLC7Sjr+MqZqSHmhKq8MWJKciRynxBeMbeGt0smExi9BqpVQdCEg==} + engines: {node: '>=8'} + dependencies: + '@sentry/core': 7.43.0 + '@sentry/replay': 7.43.0 + '@sentry/types': 7.43.0 + '@sentry/utils': 7.43.0 + tslib: 1.14.1 + dev: false + /@sentry/cli/1.74.6: resolution: {integrity: sha512-pJ7JJgozyjKZSTjOGi86chIngZMLUlYt2HOog+OJn+WGvqEkVymu8m462j1DiXAnex9NspB4zLLNuZ/R6rTQHg==} engines: {node: '>= 8'} @@ -4939,6 +4952,15 @@ packages: tslib: 1.14.1 dev: false + /@sentry/core/7.43.0: + resolution: {integrity: sha512-zvMZgEi7ptLBwDnd+xR/u4zdSe5UzS4S3ZhoemdQrn1PxsaVySD/ptyzLoGSZEABqlRxGHnQrZ78MU1hUDvKuQ==} + engines: {node: '>=8'} + dependencies: + '@sentry/types': 7.43.0 + '@sentry/utils': 7.43.0 + tslib: 1.14.1 + dev: false + /@sentry/integrations/7.36.0: resolution: {integrity: sha512-wrRoUqdeGi64NNimGVk8U8DBiXamxTYPBux0/faFDyau8EJyQFcv8zOyB78Za4W2Ss3ZXNaE/WtFF8UxalHzBQ==} engines: {node: '>=8'} @@ -4959,6 +4981,16 @@ packages: tslib: 1.14.1 dev: false + /@sentry/integrations/7.43.0: + resolution: {integrity: sha512-rob7/PAUWFTuodCDlRoB0+7vQ7Fc/LlkvprLlB1Qqt34OIgOll4T72zVSaAXWSHZz7nGU8mS2XdYkRSXbDMK4w==} + engines: {node: '>=8'} + dependencies: + '@sentry/types': 7.43.0 + '@sentry/utils': 7.43.0 + localforage: 1.10.0 + tslib: 1.14.1 + dev: false + /@sentry/nextjs/7.36.0_next@13.1.0+react@18.2.0: resolution: {integrity: sha512-7IUwBjCjo3rWuvEG16D1wKb0D+aMyCU920VGCAQVZaqTZAgrgAKfpTa1Sk0fmDxYglW1EBI9QM+WEnOa9RleLw==} engines: {node: '>=8'} @@ -5049,6 +5081,37 @@ packages: - supports-color dev: false + /@sentry/nextjs/7.43.0_next@13.2.4+react@18.2.0: + resolution: {integrity: sha512-A0cYiDNuVyxlP+FSyhM0XK0vUaT868jhHgHno6MopnF44cxYBCEBWZrXTeuHALdqBVdl2M3fdx1HX/6kjAzXTQ==} + engines: {node: '>=8'} + peerDependencies: + next: ^10.0.8 || ^11.0 || ^12.0 || ^13.0 + react: 16.x || 17.x || 18.x + webpack: '>= 4.0.0' + peerDependenciesMeta: + webpack: + optional: true + dependencies: + '@rollup/plugin-commonjs': 24.0.0_rollup@2.78.0 + '@sentry/core': 7.43.0 + '@sentry/integrations': 7.43.0 + '@sentry/node': 7.43.0 + '@sentry/react': 7.43.0_react@18.2.0 + '@sentry/tracing': 7.43.0 + '@sentry/types': 7.43.0 + '@sentry/utils': 7.43.0 + '@sentry/webpack-plugin': 1.20.0 + chalk: 3.0.0 + next: 13.2.4_biqbaboplfbrettd7655fr4n2y + react: 18.2.0 + rollup: 2.78.0 + stacktrace-parser: 0.1.10 + tslib: 1.14.1 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + /@sentry/node/7.36.0: resolution: {integrity: sha512-nAHAY+Rbn5OlTpNX/i6wYrmw3hT/BtwPZ/vNU52cKgw7CpeE1UrCeFjnPn18rQPB7lIh7x0vNvoaPrfemRzpSQ==} engines: {node: '>=8'} @@ -5079,6 +5142,21 @@ packages: - supports-color dev: false + /@sentry/node/7.43.0: + resolution: {integrity: sha512-oXaTBq6Bk8Qwsd46hhRU2MLEnjYqWI41nPJmXyAWkDSYQTP7sUe1qM8bCUdsRpPwQh955Vq9qCRfgMbN4lEoAQ==} + engines: {node: '>=8'} + dependencies: + '@sentry/core': 7.43.0 + '@sentry/types': 7.43.0 + '@sentry/utils': 7.43.0 + cookie: 0.4.2 + https-proxy-agent: 5.0.1 + lru_map: 0.3.3 + tslib: 1.14.1 + transitivePeerDependencies: + - supports-color + dev: false + /@sentry/react/7.36.0_react@18.2.0: resolution: {integrity: sha512-ttrRqbgeqvkV3DwkDRZC/V8OEnBKGpQf4dKpG8oMlfdVbMTINzrxYUgkhi9xAkxkH9O+vj3Md8L3Rdqw/SDwKQ==} engines: {node: '>=8'} @@ -5107,6 +5185,20 @@ packages: tslib: 1.14.1 dev: false + /@sentry/react/7.43.0_react@18.2.0: + resolution: {integrity: sha512-HWt0Eh+Y+Z/g+PWgeYWT6+5B+J82gauQ0GydjGeHeeSpoZRPRwWAoRFh+NKM/pe3neVr59VCyn4ghyoE3kODGA==} + engines: {node: '>=8'} + peerDependencies: + react: 15.x || 16.x || 17.x || 18.x + dependencies: + '@sentry/browser': 7.43.0 + '@sentry/types': 7.43.0 + '@sentry/utils': 7.43.0 + hoist-non-react-statics: 3.3.2 + react: 18.2.0 + tslib: 1.14.1 + dev: false + /@sentry/replay/7.36.0: resolution: {integrity: sha512-wNbME74/2GtkqdDXz7NaStyfPWVLjYmN9TFWvu6E9sNl9pkDDvii/Qc8F6ps1wa7bozkKcWRHgNvYiGCxUBHcg==} engines: {node: '>=12'} @@ -5125,6 +5217,15 @@ packages: '@sentry/utils': 7.39.0 dev: false + /@sentry/replay/7.43.0: + resolution: {integrity: sha512-2dGJS6p8uG1JZ7x/A3FyqnILTkXarbvfR+o1lC7z9lu34Wx0ZBeU2in/S2YHNGAE6XvfsePq3ya/s7LaNkk4qQ==} + engines: {node: '>=12'} + dependencies: + '@sentry/core': 7.43.0 + '@sentry/types': 7.43.0 + '@sentry/utils': 7.43.0 + dev: false + /@sentry/tracing/7.36.0: resolution: {integrity: sha512-5R5mfWMDncOcTMmmyYMjgus1vZJzIFw4LHaSbrX7e1IRNT/6vFyNeVxATa2ePXb9mI3XHo5f2p7YrnreAtaSXw==} engines: {node: '>=8'} @@ -5145,6 +5246,16 @@ packages: tslib: 1.14.1 dev: false + /@sentry/tracing/7.43.0: + resolution: {integrity: sha512-Mld2AyV8xYnRLYbDWvDy8PlGcln3h5JsUx6ScQGOxnFTmCQR50Tldtzq50VDs2fv6xH0+YrL/UIyjxCDc7EXzQ==} + engines: {node: '>=8'} + dependencies: + '@sentry/core': 7.43.0 + '@sentry/types': 7.43.0 + '@sentry/utils': 7.43.0 + tslib: 1.14.1 + dev: false + /@sentry/types/7.36.0: resolution: {integrity: sha512-uvfwUn3okAWSZ948D/xqBrkc3Sn6TeHUgi3+p/dTTNGAXXskzavgfgQ4rSW7f3YD4LL+boZojpoIARVLodMGuA==} engines: {node: '>=8'} @@ -5155,6 +5266,11 @@ packages: engines: {node: '>=8'} dev: false + /@sentry/types/7.43.0: + resolution: {integrity: sha512-5XxCWqYWJNoS+P6Ie2ZpUDxLRCt7FTEzmlQkCdjW6MFWOX26hAbF/wEuOTYAFKZXMIXOz0Egofik1e8v1Cg6/A==} + engines: {node: '>=8'} + dev: false + /@sentry/utils/7.36.0: resolution: {integrity: sha512-mgDi5X5Bm0sydCzXpnyKD/sD98yc2qnKXyRdNX4HRRwruhC/P53LT0hGhZXsyqsB/l8OAMl0zWXJLg0xONQsEw==} engines: {node: '>=8'} @@ -5171,6 +5287,14 @@ packages: tslib: 1.14.1 dev: false + /@sentry/utils/7.43.0: + resolution: {integrity: sha512-f78YfMLcgNU7+suyWFCuQhQlneXXMS+egb0EFZh7iU7kANUPRX5T4b+0C+fwaPm5gA6XfGYskr4ZnzQJLOlSqg==} + engines: {node: '>=8'} + dependencies: + '@sentry/types': 7.43.0 + tslib: 1.14.1 + dev: false + /@sentry/webpack-plugin/1.20.0: resolution: {integrity: sha512-Ssj1mJVFsfU6vMCOM2d+h+KQR7QHSfeIP16t4l20Uq/neqWXZUQ2yvQfe4S3BjdbJXz/X4Rw8Hfy1Sd0ocunYw==} engines: {node: '>= 8'} @@ -14212,6 +14336,13 @@ packages: stacktrace-gps: 3.1.2 dev: false + /stacktrace-parser/0.1.10: + resolution: {integrity: sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==} + engines: {node: '>=6'} + dependencies: + type-fest: 0.7.1 + dev: false + /state-local/1.0.7: resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==} dev: false @@ -14799,6 +14930,11 @@ packages: resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} engines: {node: '>=8'} + /type-fest/0.7.1: + resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} + engines: {node: '>=8'} + dev: false + /type-fest/0.8.1: resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} engines: {node: '>=8'}