Skip to content

Commit

Permalink
Make sure to not show pages/404 GIP error from _app having GIP (#10974)
Browse files Browse the repository at this point in the history
* Make sure to not show pages/404 GIP error from _app having GIP

* Add error for getStaticProps in pages/404 too
  • Loading branch information
ijjk committed Mar 11, 2020
1 parent 33503f7 commit 34a8e88
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 38 deletions.
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)
})
})
})
})

0 comments on commit 34a8e88

Please sign in to comment.