-
Notifications
You must be signed in to change notification settings - Fork 27.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Example update: with-sentry-simple (#8684)
* Update to capture server exceptions and more - Adds test cases for several server and client-side exceptions - Allows capturing more server-side exceptions by overriding _error.js and using Sentry.captureException() within - Use @sentry/node on the server - Rely on Next.js's React Error Boundary instead of creating our own in _app.js * Update test notes Found some differences while testing in production * Remove accidental mount throw on test 8 * Add note about server-side source maps * Linting fixes
- Loading branch information
1 parent
aa98323
commit dc28e5b
Showing
19 changed files
with
447 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,25 @@ | ||
const withSourceMaps = require('@zeit/next-source-maps')() | ||
|
||
module.exports = withSourceMaps({ | ||
webpack (config, _options) { | ||
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 | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
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 <Error statusCode={statusCode} /> | ||
} | ||
|
||
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import React from 'react' | ||
|
||
const Test1 = () => <h1>Client Test 1</h1> | ||
|
||
Test1.getInitialProps = () => { | ||
throw new Error('Client Test 1') | ||
} | ||
|
||
export default Test1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import React from 'react' | ||
|
||
const Test2 = () => <h1>Client Test 2</h1> | ||
|
||
Test2.getInitialProps = () => Promise.reject(new Error('Client Test 2')) | ||
|
||
export default Test2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import React from 'react' | ||
|
||
const Test3 = () => <h1>Client Test 3</h1> | ||
|
||
Test3.getInitialProps = () => { | ||
const doAsyncWork = () => Promise.reject(new Error('Client Test 3')) | ||
|
||
doAsyncWork() | ||
|
||
return {} | ||
} | ||
|
||
export default Test3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import React from 'react' | ||
|
||
const doAsyncWork = () => Promise.reject(new Error('Client Test 4')) | ||
doAsyncWork() | ||
|
||
const Test4 = () => <h1>Client Test 4</h1> | ||
|
||
export default Test4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import React from 'react' | ||
|
||
// This code will run just fine on the server in Node.js, but process will be | ||
// undefined in a browser. Note that `isProd = process.env.NODE_ENV` would have | ||
// worked because Webpack's DefinePlugin will replace it with a string at build | ||
// time: https://nextjs.org/docs#build-time-configuration | ||
const env = process.env | ||
const isProd = env.NODE_ENV === 'production' | ||
|
||
const Test5 = () => ( | ||
<React.Fragment> | ||
<h1>Client Test 5</h1> | ||
<p> | ||
isProd: {isProd} | ||
</p> | ||
</React.Fragment> | ||
) | ||
|
||
export default Test5 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import React from 'react' | ||
|
||
const Test6 = () => { | ||
React.useEffect(() => { | ||
throw new Error('Client Test 6') | ||
}, []) | ||
|
||
return <h1>Client Test 6</h1> | ||
} | ||
|
||
export default Test6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import React from 'react' | ||
|
||
const Test7 = () => { | ||
React.useEffect(async () => { | ||
const doAsyncWork = () => Promise.reject(new Error('Client Test 7')) | ||
const result = await doAsyncWork() | ||
console.log(result) | ||
}, []) | ||
|
||
return <h1>Client Test 7</h1> | ||
} | ||
|
||
export default Test7 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import React from 'react' | ||
|
||
const Test8 = () => ( | ||
<React.Fragment> | ||
<h1>Client Test 8</h1> | ||
<button | ||
onClick={() => { | ||
throw new Error('Client Test 8') | ||
}} | ||
> | ||
Click me to throw an Error | ||
</button> | ||
</React.Fragment> | ||
) | ||
|
||
export default Test8 |
Oops, something went wrong.