From b9c71d373c50f2cb7ba7830fdb2c202f9ad200c4 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Wed, 6 Nov 2019 09:32:28 -0800 Subject: [PATCH] Revert experimental plugins code from sentry example (#9317) --- examples/with-sentry-simple/next.config.js | 25 ++++++-- examples/with-sentry-simple/package.json | 3 +- examples/with-sentry-simple/pages/_app.js | 22 +++++++ examples/with-sentry-simple/pages/_error.js | 66 +++++++++++++++++++++ 4 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 examples/with-sentry-simple/pages/_app.js create mode 100644 examples/with-sentry-simple/pages/_error.js diff --git a/examples/with-sentry-simple/next.config.js b/examples/with-sentry-simple/next.config.js index ae027a74e1..1d920c7ce9 100644 --- a/examples/with-sentry-simple/next.config.js +++ b/examples/with-sentry-simple/next.config.js @@ -1,10 +1,25 @@ const withSourceMaps = require('@zeit/next-source-maps')() module.exports = withSourceMaps({ - env: { - SENTRY_DSN: 'hello-world', - // would want to synchronously grab git commit id here for - // best debugging experience - SENTRY_RELEASE: '0.0.1' + webpack: (config, options) => { + // In `pages/_app.js`, Sentry is imported from @sentry/node. While + // @sentry/browser will run in a Node.js environment, @sentry/node will use + // Node.js-only APIs to catch even more unhandled exceptions. + // + // This works well when Next.js is SSRing your page on a server with + // Node.js, but it is not what we want when your client-side bundle is being + // executed by a browser. + // + // Luckily, Next.js will call this webpack function twice, once for the + // server and once for the client. Read more: + // https://nextjs.org/docs#customizing-webpack-config + // + // So ask Webpack to replace @sentry/node imports with @sentry/browser when + // building the browser's bundle + if (!options.isServer) { + config.resolve.alias['@sentry/node'] = '@sentry/browser' + } + + return config } }) diff --git a/examples/with-sentry-simple/package.json b/examples/with-sentry-simple/package.json index 0f9cb0fccf..ed32fcf41b 100644 --- a/examples/with-sentry-simple/package.json +++ b/examples/with-sentry-simple/package.json @@ -8,7 +8,8 @@ "start": "next start" }, "dependencies": { - "@next/plugin-sentry": "latest", + "@sentry/browser": "^5.1.0", + "@sentry/node": "^5.6.2", "next": "latest", "react": "^16.8.6", "react-dom": "^16.8.6" diff --git a/examples/with-sentry-simple/pages/_app.js b/examples/with-sentry-simple/pages/_app.js new file mode 100644 index 0000000000..cb770b19cc --- /dev/null +++ b/examples/with-sentry-simple/pages/_app.js @@ -0,0 +1,22 @@ +import React from 'react' +import App from 'next/app' +import * as Sentry from '@sentry/node' + +Sentry.init({ + // Replace with your project's Sentry DSN + dsn: 'https://00000000000000000000000000000000@sentry.io/1111111' +}) + +class MyApp extends App { + render () { + const { Component, pageProps } = this.props + + // Workaround for https://github.com/zeit/next.js/issues/8592 + const { err } = this.props + const modifiedPageProps = { ...pageProps, err } + + return + } +} + +export default MyApp diff --git a/examples/with-sentry-simple/pages/_error.js b/examples/with-sentry-simple/pages/_error.js new file mode 100644 index 0000000000..629564f4e8 --- /dev/null +++ b/examples/with-sentry-simple/pages/_error.js @@ -0,0 +1,66 @@ +import React from 'react' +import Error from 'next/error' +import * as Sentry from '@sentry/node' + +const MyError = ({ statusCode, hasGetInitialPropsRun, err }) => { + if (!hasGetInitialPropsRun && err) { + // getInitialProps is not called in case of + // https://github.com/zeit/next.js/issues/8592. As a workaround, we pass + // err via _app.js so it can be captured + Sentry.captureException(err) + } + + return +} + +MyError.getInitialProps = async ({ res, err, asPath }) => { + const errorInitialProps = await Error.getInitialProps({ res, err }) + + // Workaround for https://github.com/zeit/next.js/issues/8592, mark when + // getInitialProps has run + errorInitialProps.hasGetInitialPropsRun = true + + if (res) { + // Running on the server, the response object is available. + // + // Next.js will pass an err on the server if a page's `getInitialProps` + // threw or returned a Promise that rejected + + if (res.statusCode === 404) { + // Opinionated: do not record an exception in Sentry for 404 + return { statusCode: 404 } + } + + if (err) { + Sentry.captureException(err) + + return errorInitialProps + } + } else { + // Running on the client (browser). + // + // Next.js will provide an err if: + // + // - a page's `getInitialProps` threw or returned a Promise that rejected + // - an exception was thrown somewhere in the React lifecycle (render, + // componentDidMount, etc) that was caught by Next.js's React Error + // Boundary. Read more about what types of exceptions are caught by Error + // Boundaries: https://reactjs.org/docs/error-boundaries.html + if (err) { + Sentry.captureException(err) + + return errorInitialProps + } + } + + // If this point is reached, getInitialProps was called without any + // information about what the error might be. This is unexpected and may + // indicate a bug introduced in Next.js, so record it in Sentry + Sentry.captureException( + new Error(`_error.js getInitialProps missing data at path: ${asPath}`) + ) + + return errorInitialProps +} + +export default MyError -- GitLab