1
0
Fork 0
mirror of https://github.com/terribleplan/next.js.git synced 2024-01-19 02:48:18 +00:00

Only show 404 when the page does not exist (#3976)

* Only show 404 when the page does not exist

* Do async filesystem check
This commit is contained in:
Tim Neutkens 2018-03-09 17:14:30 +01:00 committed by GitHub
parent 4757836a67
commit 7e9f4f9327
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 26 deletions

View file

@ -55,8 +55,10 @@ async function doRender (req, res, pathname, query, {
const documentPath = join(dir, dist, 'dist', 'bundles', 'pages', '_document')
let Component = requirePage(page, {dir, dist})
let Document = require(documentPath)
let [Component, Document] = await Promise.all([
requirePage(page, {dir, dist}),
require(documentPath)
])
Component = Component.default || Component
Document = Document.default || Document
const asPath = req.url

View file

@ -1,4 +1,5 @@
import {join, parse, normalize, sep} from 'path'
import fs from 'mz/fs'
export function pageNotFoundError (page) {
const err = new Error(`Cannot find module for page: ${page}`)
@ -53,19 +54,12 @@ export function getPagePath (page, {dir, dist}) {
return pagePath
}
export default function requirePage (page, {dir, dist}) {
const pagePath = getPagePath(page, {dir, dist})
try {
return require(pagePath)
} catch (err) {
if (err.code === 'MODULE_NOT_FOUND') {
throw pageNotFoundError(page)
}
console.error(err)
// If this is not a MODULE_NOT_FOUND error,
// it should be something with the content of the page.
// So, Next.js rendering system will catch it and process.
throw err
export default async function requirePage (page, {dir, dist}) {
const pagePath = getPagePath(page, {dir, dist}) + '.js'
const fileExists = await fs.exists(pagePath)
if (!fileExists) {
throw pageNotFoundError(page)
}
return require(pagePath)
}

View file

@ -0,0 +1,4 @@
const nonExistent = require('./non-existent-module')
module.exports = {
test: nonExistent
}

View file

@ -57,26 +57,42 @@ describe('getPagePath', () => {
})
describe('requirePage', () => {
it('Should require /index.js when using /', () => {
const page = requirePage('/', {dir: __dirname, dist: '_resolvedata'})
it('Should require /index.js when using /', async () => {
const page = await requirePage('/', {dir: __dirname, dist: '_resolvedata'})
expect(page.test).toBe('hello')
})
it('Should require /index.js when using /index', () => {
const page = requirePage('/index', {dir: __dirname, dist: '_resolvedata'})
it('Should require /index.js when using /index', async () => {
const page = await requirePage('/index', {dir: __dirname, dist: '_resolvedata'})
expect(page.test).toBe('hello')
})
it('Should require /world.js when using /world', () => {
const page = requirePage('/world', {dir: __dirname, dist: '_resolvedata'})
it('Should require /world.js when using /world', async () => {
const page = await requirePage('/world', {dir: __dirname, dist: '_resolvedata'})
expect(page.test).toBe('world')
})
it('Should throw when using /../../test.js', () => {
expect(() => requirePage('/../../test.js', {dir: __dirname, dist: '_resolvedata'})).toThrow()
it('Should throw when using /../../test.js', async () => {
try {
await requirePage('/../../test', {dir: __dirname, dist: '_resolvedata'})
} catch (err) {
expect(err.code).toBe('ENOENT')
}
})
it('Should throw when using non existent pages like /non-existent.js', () => {
expect(() => requirePage('/non-existent.js', {dir: __dirname, dist: '_resolvedata'})).toThrow()
it('Should throw when using non existent pages like /non-existent.js', async () => {
try {
await requirePage('/non-existent', {dir: __dirname, dist: '_resolvedata'})
} catch (err) {
expect(err.code).toBe('ENOENT')
}
})
it('Should bubble up errors in the child component', async () => {
try {
await requirePage('/non-existent-child', {dir: __dirname, dist: '_resolvedata'})
} catch (err) {
expect(err.code).toBe('MODULE_NOT_FOUND')
}
})
})