Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make sure to not show pages/404 GIP error from _app having GIP #10974

Merged
merged 2 commits into from Mar 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/next/lib/constants.ts
Expand Up @@ -30,4 +30,4 @@ export const SERVER_PROPS_GET_INIT_PROPS_CONFLICT = `You can not use getInitialP

export const SERVER_PROPS_SSG_CONFLICT = `You can not use getStaticProps with getServerSideProps. To use SSG, please remove getServerSideProps`

export const PAGES_404_GET_INITIAL_PROPS_ERROR = `\`pages/404\` can not have getInitialProps/getServerSideProps, https://err.sh/zeit/next.js/404-get-initial-props`
export const PAGES_404_GET_INITIAL_PROPS_ERROR = `\`pages/404\` can not have getInitialProps/getServerSideProps/getStaticProps, https://err.sh/zeit/next.js/404-get-initial-props`
5 changes: 4 additions & 1 deletion packages/next/next-server/server/render.tsx
Expand Up @@ -418,7 +418,10 @@ export async function renderToHTML(
renderOpts.nextExport = true
}

if (pathname === '/404' && !isAutoExport) {
if (
pathname === '/404' &&
(hasPageGetInitialProps || getServerSideProps || isSSG)
) {
throw new Error(PAGES_404_GET_INITIAL_PROPS_ERROR)
}
}
Expand Down
201 changes: 165 additions & 36 deletions test/integration/404-page/test/index.test.js
Expand Up @@ -19,6 +19,7 @@ const appDir = join(__dirname, '../')
const pages404 = join(appDir, 'pages/404.js')
const appPage = join(appDir, 'pages/_app.js')
const nextConfig = join(appDir, 'next.config.js')
const gip404Err = /`pages\/404` can not have getInitialProps\/getServerSideProps/

let nextConfigContent
let buildId
Expand Down Expand Up @@ -148,9 +149,7 @@ describe('404 Page Support', () => {
await fs.remove(pages404)
await fs.move(`${pages404}.bak`, pages404)

expect(stderr).toContain(
`\`pages/404\` can not have getInitialProps/getServerSideProps, https://err.sh/zeit/next.js/404-get-initial-props`
)
expect(stderr).toMatch(gip404Err)
expect(code).toBe(1)
})

Expand Down Expand Up @@ -180,51 +179,181 @@ describe('404 Page Support', () => {
await fs.remove(pages404)
await fs.move(`${pages404}.bak`, pages404)

const error = `\`pages/404\` can not have getInitialProps/getServerSideProps, https://err.sh/zeit/next.js/404-get-initial-props`
expect(stderr).toMatch(gip404Err)
})

it('shows error with getStaticProps in pages/404 build', async () => {
await fs.move(pages404, `${pages404}.bak`)
await fs.writeFile(
pages404,
`
const page = () => 'custom 404 page'
export const getStaticProps = () => ({ props: { a: 'b' } })
export default page
`
)
const { stderr, code } = await nextBuild(appDir, [], { stderr: true })
await fs.remove(pages404)
await fs.move(`${pages404}.bak`, pages404)

expect(stderr).toMatch(gip404Err)
expect(code).toBe(1)
})

it('shows error with getStaticProps in pages/404 dev', async () => {
await fs.move(pages404, `${pages404}.bak`)
await fs.writeFile(
pages404,
`
const page = () => 'custom 404 page'
export const getStaticProps = () => ({ props: { a: 'b' } })
export default page
`
)

let stderr = ''
appPort = await findPort()
app = await launchApp(appDir, appPort, {
onStderr(msg) {
stderr += msg || ''
},
})
await renderViaHTTP(appPort, '/abc')
await waitFor(1000)

await killApp(app)

await fs.remove(pages404)
await fs.move(`${pages404}.bak`, pages404)

expect(stderr).toMatch(gip404Err)
})

it('shows error with getServerSideProps in pages/404 build', async () => {
await fs.move(pages404, `${pages404}.bak`)
await fs.writeFile(
pages404,
`
const page = () => 'custom 404 page'
export const getServerSideProps = () => ({ props: { a: 'b' } })
export default page
`
)
const { stderr, code } = await nextBuild(appDir, [], { stderr: true })
await fs.remove(pages404)
await fs.move(`${pages404}.bak`, pages404)

expect(stderr).toMatch(gip404Err)
expect(code).toBe(1)
})

it('shows error with getServerSideProps in pages/404 dev', async () => {
await fs.move(pages404, `${pages404}.bak`)
await fs.writeFile(
pages404,
`
const page = () => 'custom 404 page'
export const getServerSideProps = () => ({ props: { a: 'b' } })
export default page
`
)

let stderr = ''
appPort = await findPort()
app = await launchApp(appDir, appPort, {
onStderr(msg) {
stderr += msg || ''
},
})
await renderViaHTTP(appPort, '/abc')
await waitFor(1000)

await killApp(app)

await fs.remove(pages404)
await fs.move(`${pages404}.bak`, pages404)

expect(stderr).toContain(error)
expect(stderr).toMatch(gip404Err)
})

describe('_app with getInitialProps', () => {
beforeAll(async () => {
await fs.writeFile(
beforeAll(() =>
fs.writeFile(
appPage,
`
import NextApp from 'next/app'
const App = ({ Component, pageProps }) => <Component {...pageProps} />
App.getInitialProps = NextApp.getInitialProps
export default App
`
import NextApp from 'next/app'
const App = ({ Component, pageProps }) => <Component {...pageProps} />
App.getInitialProps = NextApp.getInitialProps
export default App
`
)
await nextBuild(appDir)
appPort = await findPort()
app = await nextStart(appDir, appPort)
buildId = await fs.readFile(join(appDir, '.next/BUILD_ID'), 'utf8')
})
afterAll(async () => {
await fs.remove(appPage)
await killApp(app)
})
)
afterAll(() => fs.remove(appPage))

it('should not output static 404 if _app has getInitialProps', async () => {
expect(
await fs.exists(
join(appDir, '.next/server/static', buildId, 'pages/404.html')
describe('production mode', () => {
afterAll(() => killApp(app))

it('should build successfully', async () => {
const { code, stderr, stdout } = await nextBuild(appDir, [], {
stderr: true,
stdout: true,
})

expect(code).toBe(0)
expect(stderr).not.toMatch(gip404Err)
expect(stdout).not.toMatch(gip404Err)

appPort = await findPort()
app = await nextStart(appDir, appPort)
buildId = await fs.readFile(join(appDir, '.next/BUILD_ID'), 'utf8')
})

it('should not output static 404 if _app has getInitialProps', async () => {
expect(
await fs.exists(
join(appDir, '.next/server/static', buildId, 'pages/404.html')
)
).toBe(false)
})

it('specify to use the 404 page still in the routes-manifest', async () => {
const manifest = await fs.readJSON(
join(appDir, '.next/routes-manifest.json')
)
).toBe(false)
})
expect(manifest.pages404).toBe(true)
})

it('specify to use the 404 page still in the routes-manifest', async () => {
const manifest = await fs.readJSON(
join(appDir, '.next/routes-manifest.json')
)
expect(manifest.pages404).toBe(true)
it('should still use 404 page', async () => {
const res = await fetchViaHTTP(appPort, '/abc')
expect(res.status).toBe(404)
expect(await res.text()).toContain('custom 404 page')
})
})

it('should still use 404 page', async () => {
const res = await fetchViaHTTP(appPort, '/abc')
expect(res.status).toBe(404)
expect(await res.text()).toContain('custom 404 page')
describe('dev mode', () => {
let stderr = ''
let stdout = ''

beforeAll(async () => {
appPort = await findPort()
app = await launchApp(appDir, appPort, {
onStderr(msg) {
stderr += msg
},
onStdout(msg) {
stdout += msg
},
})
})
afterAll(() => killApp(app))

it('should not show pages/404 GIP error if _app has GIP', async () => {
const res = await fetchViaHTTP(appPort, '/abc')
expect(res.status).toBe(404)
expect(await res.text()).toContain('custom 404 page')
expect(stderr).not.toMatch(gip404Err)
expect(stdout).not.toMatch(gip404Err)
})
})
})
})