|
1 | | -import NextErrorComponent from 'next/error' |
| 1 | +/** |
| 2 | + * This page is loaded by Nextjs: |
| 3 | + * - on the server, when data-fetching methods throw or reject |
| 4 | + * - on the client, when `getInitialProps` throws or rejects |
| 5 | + * - on the client, when a React lifecycle method throws or rejects, and it's |
| 6 | + * caught by the built-in Nextjs error boundary |
| 7 | + * |
| 8 | + * See: |
| 9 | + * - https://nextjs.org/docs/basic-features/data-fetching/overview |
| 10 | + * - https://nextjs.org/docs/api-reference/data-fetching/get-initial-props |
| 11 | + * - https://reactjs.org/docs/error-boundaries.html |
| 12 | + */ |
2 | 13 |
|
3 | 14 | import * as Sentry from '@sentry/nextjs' |
| 15 | +import NextErrorComponent from 'next/error' |
4 | 16 |
|
5 | | -const MyError = ({ statusCode, hasGetInitialPropsRun, err }) => { |
6 | | - if (!hasGetInitialPropsRun && err) { |
7 | | - // getInitialProps is not called in case of |
8 | | - // https://github.com/vercel/next.js/issues/8592. As a workaround, we pass |
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 | | - } |
13 | | - |
14 | | - return <NextErrorComponent statusCode={statusCode} /> |
15 | | -} |
16 | | - |
17 | | -MyError.getInitialProps = async ({ res, err }) => { |
18 | | - const errorInitialProps = await NextErrorComponent.getInitialProps({ |
19 | | - res, |
20 | | - err, |
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) |
| 17 | +const CustomErrorComponent = (props) => ( |
| 18 | + <NextErrorComponent statusCode={props.statusCode} /> |
| 19 | +) |
46 | 20 |
|
47 | | - return errorInitialProps |
48 | | - } |
| 21 | +CustomErrorComponent.getInitialProps = async (contextData) => { |
| 22 | + // In case this is running in a serverless function, await this in order to give Sentry |
| 23 | + // time to send the error before the lambda exits |
| 24 | + await Sentry.captureUnderscoreErrorException(contextData) |
49 | 25 |
|
50 | | - // If this point is reached, getInitialProps was called without any |
51 | | - // information about what the error might be. This can be caused by |
52 | | - // a falsy value being thrown e.g. throw undefined |
53 | | - return errorInitialProps |
| 26 | + // This will contain the status code of the response |
| 27 | + return NextErrorComponent.getInitialProps(contextData) |
54 | 28 | } |
55 | 29 |
|
56 | | -export default MyError |
| 30 | +export default CustomErrorComponent |
0 commit comments