fix: improve error when starting next
without building (#62404)
Addresses #57066 Currently, a user running `next start` on an un-built Next.js project receives a confusing uncaught error before the process just ends: ``` ▲ Next.js 14.1.0 - Local: http://localhost:3000 [Error: ENOENT: no such file or directory, open '/home/flotwig/src/project/.next/BUILD_ID'] { errno: -2, code: 'ENOENT', syscall: 'open', path: '/home/flotwig/src/project/.next/BUILD_ID' } ``` In my case, I ran into this because I had not worked with Next.js for a while, and I forgot that `next dev` was used for local development, not `next start`. I believe many of the confused users in #57066 are making a similar mistake and not realizing it, due to the error message. This PR catches an `ENOENT` when reading `BUILD_ID` and suggests that the user `next build` or `next dev` to remove this friction point: ``` ▲ Next.js 14.1.1-canary.69 - Local: http://localhost:3000 Error: Could not find a production build in the '.next' directory. Try building your app with 'next build' before starting the production server. https://nextjs.org/docs/messages/production-start-no-build-id at setupFsCheck (/home/flotwig/src/next.js/packages/next/src/server/lib/router-utils/filesystem.ts:157:13) at initialize (/home/flotwig/src/next.js/packages/next/src/server/lib/router-server.ts:90:21) at Server.<anonymous> (/home/flotwig/src/next.js/packages/next/src/server/lib/start-server.ts:295:28) ``` A few things probably need to be resolved before this PR can merge, I would appreciate any input from Next.js maintainers. - [x] Is this the best place to catch this? I am not familiar with the Next.js codebase, so I just caught this in the most obvious way. - [x] Can the error message be improved? - [x] Add a test for the error in `test/development` --------- Co-authored-by: JJ Kasper <jj@jjsweb.site>
This commit is contained in:
parent
036a4f60fc
commit
f72debcf48
3 changed files with 30 additions and 1 deletions
|
@ -150,7 +150,14 @@ export async function setupFsCheck(opts: {
|
|||
|
||||
if (!opts.dev) {
|
||||
const buildIdPath = path.join(opts.dir, opts.config.distDir, BUILD_ID_FILE)
|
||||
buildId = await fs.readFile(buildIdPath, 'utf8')
|
||||
try {
|
||||
buildId = await fs.readFile(buildIdPath, 'utf8')
|
||||
} catch (err: any) {
|
||||
if (err.code !== 'ENOENT') throw err
|
||||
throw new Error(
|
||||
`Could not find a production build in the '${opts.config.distDir}' directory. Try building your app with 'next build' before starting the production server. https://nextjs.org/docs/messages/production-start-no-build-id`
|
||||
)
|
||||
}
|
||||
|
||||
try {
|
||||
for (const file of await recursiveReadDir(publicFolderPath)) {
|
||||
|
|
0
test/development/start-no-build/app/.gitkeep
Normal file
0
test/development/start-no-build/app/.gitkeep
Normal file
22
test/development/start-no-build/start-no-build.test.ts
Normal file
22
test/development/start-no-build/start-no-build.test.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
import { createNext } from 'e2e-utils'
|
||||
|
||||
describe('next start without next build', () => {
|
||||
it('should show error when there is no production build', async () => {
|
||||
const next = await createNext({
|
||||
files: __dirname,
|
||||
skipStart: true,
|
||||
startCommand: `pnpm next start`,
|
||||
})
|
||||
|
||||
await next.start()
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
next.on('stderr', (msg) => {
|
||||
if (msg.includes('Could not find a production build in the')) {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
await next.destroy()
|
||||
})
|
||||
})
|
Loading…
Reference in a new issue