Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions packages/next/src/server/route-modules/pages/pages-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -693,11 +693,10 @@ export const getHandler = ({
}

// when invoking _error before pages/500 we don't actually
// send the _error response
if (
getRequestMeta(req, 'customErrorRender') ||
(isErrorPage && isMinimalMode && res.statusCode === 500)
) {
// send the _error response - only skip if customErrorRender is set
// (meaning pages/500 exists and will be rendered next), or if using
// the builtin _error in minimalMode to allow error bubbling
if (getRequestMeta(req, 'customErrorRender')) {
return null
}

Expand Down
6 changes: 6 additions & 0 deletions test/production/pages-get-initial-props-error/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* @type {import('next').NextConfig}
*/
const nextConfig = {}

module.exports = nextConfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { nextTestSetup } from 'e2e-utils'

describe('pages-get-initial-props-error', () => {
const { next } = nextTestSetup({
files: __dirname,
})

it('should render _error with 500 status code when getInitialProps throws', async () => {
const browser = await next.browser('/gip-error')
expect(await browser.elementByCss('p').text()).toBe(
'An error 500 occurred on server'
)

const response = await next.fetch('/gip-error')
expect(response.status).toBe(500)
})
})
5 changes: 5 additions & 0 deletions test/production/pages-get-initial-props-error/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { AppProps } from 'next/app'

export default function App({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}
13 changes: 13 additions & 0 deletions test/production/pages-get-initial-props-error/pages/_document.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Html, Head, Main, NextScript } from 'next/document'

export default function Document() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
38 changes: 38 additions & 0 deletions test/production/pages-get-initial-props-error/pages/_error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import type { NextPageContext } from 'next'

type ErrorProps = {
statusCode?: number
}

function ErrorPage({ statusCode }: ErrorProps) {
return (
<p>
{statusCode !== undefined
? `An error ${statusCode} occurred on server`
: 'An error occurred on client'}
</p>
)
}

ErrorPage.getInitialProps = ({ res, err }: NextPageContext) => {
console.log('ErrorPage.gip:err', err, '!!res', !!res)
let statusCode = 200
try {
statusCode = res?.statusCode ?? err?.statusCode ?? (res || err ? 500 : 404)
} catch (error) {
console.error('ErrorPage.gip:try-catch', error)
}

console.trace(
'ErrorPage.status code',
'res?.statusCode',
res?.statusCode,
'err?.statusCode',
err?.statusCode,
'final',
statusCode
)
return { statusCode }
}

export default ErrorPage
21 changes: 21 additions & 0 deletions test/production/pages-get-initial-props-error/pages/gip-error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { GetServerSideProps } from 'next'

class IntentionalServerError extends Error {
statusCode: number

constructor(message: string, statusCode = 500) {
super(message)
this.name = 'IntentionalServerError'
this.statusCode = statusCode
}
}

export default function ErrorDemo() {
return <h1>Custom Error Page Demo</h1>
}

export const getServerSideProps: GetServerSideProps = async () => {
throw new IntentionalServerError(
'Intentional error triggered via getServerSideProps.'
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -551,19 +551,19 @@ describe('Required Server Files', () => {
it('should bubble error correctly for gip page', async () => {
const res = await fetchViaHTTP(appPort, '/errors/gip', { crash: '1' })
expect(res.status).toBe(500)
expect(await res.text()).toBe('Internal Server Error')
expect(await res.text()).toContain('500 - Internal Server Error.')
})

it('should bubble error correctly for gssp page', async () => {
const res = await fetchViaHTTP(appPort, '/errors/gssp', { crash: '1' })
expect(res.status).toBe(500)
expect(await res.text()).toBe('Internal Server Error')
expect(await res.text()).toContain('500 - Internal Server Error.')
})

it('should bubble error correctly for gsp page', async () => {
const res = await fetchViaHTTP(appPort, '/errors/gsp/crash')
expect(res.status).toBe(500)
expect(await res.text()).toBe('Internal Server Error')
expect(await res.text()).toContain('500 - Internal Server Error.')
})

it('should normalize optional values correctly for SSP page', async () => {
Expand Down
Loading