diff --git a/packages/nextjs/src/config/wrappers/withSentryServerSideAppGetInitialProps.ts b/packages/nextjs/src/config/wrappers/withSentryServerSideAppGetInitialProps.ts index 3af686c18618..87c7addbfd58 100644 --- a/packages/nextjs/src/config/wrappers/withSentryServerSideAppGetInitialProps.ts +++ b/packages/nextjs/src/config/wrappers/withSentryServerSideAppGetInitialProps.ts @@ -45,6 +45,15 @@ export function withSentryServerSideAppGetInitialProps(origAppGetInitialProps: A }); const requestTransaction = getTransactionFromRequest(req); + + // Per definition, `pageProps` is not optional, however an increased amount of users doesn't seem to call + // `App.getInitialProps(appContext)` in their custom `_app` pages which is required as per + // https://nextjs.org/docs/advanced-features/custom-app - resulting in missing `pageProps`. + // For this reason, we just handle the case where `pageProps` doesn't exist explicitly. + if (!appGetInitialProps.pageProps) { + appGetInitialProps.pageProps = {}; + } + if (requestTransaction) { appGetInitialProps.pageProps._sentryTraceData = requestTransaction.toTraceparent(); diff --git a/packages/nextjs/test/integration/pages/_app.tsx b/packages/nextjs/test/integration/pages/_app.tsx new file mode 100644 index 000000000000..da1ab1154f15 --- /dev/null +++ b/packages/nextjs/test/integration/pages/_app.tsx @@ -0,0 +1,18 @@ +import App, { AppContext, AppProps } from 'next/app'; + +const MyApp = ({ Component, pageProps }: AppProps) => { + return ; +}; + +MyApp.getInitialProps = async (appContext: AppContext) => { + // This simulates user misconfiguration. Users should always call `App.getInitialProps(appContext)`, but they don't, + // so we have a test for this so we don't break their apps. + if (appContext.ctx.pathname === '/faultyAppGetInitialProps') { + return {}; + } + + const appProps = await App.getInitialProps(appContext); + return { ...appProps }; +}; + +export default MyApp; diff --git a/packages/nextjs/test/integration/pages/faultyAppGetInitialProps.tsx b/packages/nextjs/test/integration/pages/faultyAppGetInitialProps.tsx new file mode 100644 index 000000000000..fabe09909a44 --- /dev/null +++ b/packages/nextjs/test/integration/pages/faultyAppGetInitialProps.tsx @@ -0,0 +1,4 @@ +// See _app.tsx for more information why this file exists. +const Page = (): JSX.Element =>

Hello World!

; + +export default Page; diff --git a/packages/nextjs/test/integration/test/client/faultyAppGetInitialPropsConfiguration.js b/packages/nextjs/test/integration/test/client/faultyAppGetInitialPropsConfiguration.js new file mode 100644 index 000000000000..025e05d7216b --- /dev/null +++ b/packages/nextjs/test/integration/test/client/faultyAppGetInitialPropsConfiguration.js @@ -0,0 +1,11 @@ +const expect = require('expect'); + +// This test verifies that a faulty configuration of `getInitialProps` in `_app` will not cause our +// auto - wrapping / instrumentation to throw an error. +// See `_app.tsx` for more information. + +module.exports = async ({ page, url }) => { + await page.goto(`${url}/faultyAppGetInitialProps`); + const serverErrorText = await page.$x('//*[contains(text(), "Internal Server Error")]'); + expect(serverErrorText).toHaveLength(0); +};