Skip to content

Commit 3f94f33

Browse files
authoredFeb 11, 2021
Ensure error is passed up in minimal mode (#22030)
This ensures we pass the error up to the top-level when in minimal mode
1 parent 6b99bda commit 3f94f33

File tree

5 files changed

+109
-8
lines changed

5 files changed

+109
-8
lines changed
 

‎packages/next/next-server/server/next-server.ts

+21-7
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ export default class Server {
184184
this.nextConfig = loadConfig(phase, this.dir, conf)
185185
this.distDir = join(this.dir, this.nextConfig.distDir)
186186
this.publicDir = join(this.dir, CLIENT_PUBLIC_FILES_PATH)
187-
this.hasStaticDir = fs.existsSync(join(this.dir, 'static'))
187+
this.hasStaticDir = !minimalMode && fs.existsSync(join(this.dir, 'static'))
188188

189189
// Only serverRuntimeConfig needs the default
190190
// publicRuntimeConfig gets it's default in client/index.js
@@ -567,6 +567,9 @@ export default class Server {
567567
try {
568568
return await this.run(req, res, parsedUrl)
569569
} catch (err) {
570+
if (this.minimalMode) {
571+
throw err
572+
}
570573
this.logError(err)
571574
res.statusCode = 500
572575
res.end('Internal Server Error')
@@ -1835,14 +1838,19 @@ export default class Server {
18351838
}
18361839
}
18371840
} catch (err) {
1838-
this.logError(err)
1839-
18401841
if (err && err.code === 'DECODE_FAILED') {
1842+
this.logError(err)
18411843
res.statusCode = 400
18421844
return await this.renderErrorToHTML(err, req, res, pathname, query)
18431845
}
18441846
res.statusCode = 500
1845-
return await this.renderErrorToHTML(err, req, res, pathname, query)
1847+
const html = await this.renderErrorToHTML(err, req, res, pathname, query)
1848+
1849+
if (this.minimalMode) {
1850+
throw err
1851+
}
1852+
this.logError(err)
1853+
return html
18461854
}
18471855
res.statusCode = 404
18481856
return await this.renderErrorToHTML(null, req, res, pathname, query)
@@ -1863,6 +1871,10 @@ export default class Server {
18631871
)
18641872
}
18651873
const html = await this.renderErrorToHTML(err, req, res, pathname, query)
1874+
1875+
if (this.minimalMode && res.statusCode === 500) {
1876+
throw err
1877+
}
18661878
if (html === null) {
18671879
return
18681880
}
@@ -2007,9 +2019,11 @@ export default class Server {
20072019
}
20082020

20092021
let nextFilesStatic: string[] = []
2010-
nextFilesStatic = recursiveReadDirSync(
2011-
join(this.distDir, 'static')
2012-
).map((f) => join('.', relative(this.dir, this.distDir), 'static', f))
2022+
nextFilesStatic = !this.minimalMode
2023+
? recursiveReadDirSync(join(this.distDir, 'static')).map((f) =>
2024+
join('.', relative(this.dir, this.distDir), 'static', f)
2025+
)
2026+
: []
20132027

20142028
return (this._validFilesystemPathSet = new Set<string>([
20152029
...nextFilesStatic,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
function Page(props) {
2+
return <p>here comes an error</p>
3+
}
4+
5+
Page.getInitialProps = ({ query }) => {
6+
if (query.crash) {
7+
throw new Error('gip hit an oops')
8+
}
9+
return {
10+
hello: 'world',
11+
}
12+
}
13+
14+
export default Page
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { useRouter } from 'next/router'
2+
3+
function Page(props) {
4+
if (useRouter().isFallback) {
5+
return <p>loading...</p>
6+
}
7+
return <p>here comes an error</p>
8+
}
9+
10+
export const getStaticPaths = () => {
11+
return {
12+
paths: [],
13+
fallback: true,
14+
}
15+
}
16+
17+
export const getStaticProps = ({ params }) => {
18+
if (params.post === 'crash') {
19+
throw new Error('gsp hit an oops')
20+
}
21+
return {
22+
props: {
23+
hello: 'world',
24+
},
25+
}
26+
}
27+
28+
export default Page
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
function Page(props) {
2+
return <p>here comes an error</p>
3+
}
4+
5+
export const getServerSideProps = ({ query }) => {
6+
if (query.crash) {
7+
throw new Error('gssp hit an oops')
8+
}
9+
return {
10+
props: {
11+
hello: 'world',
12+
},
13+
}
14+
}
15+
16+
export default Page

‎test/integration/required-server-files/test/index.test.js

+30-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ let nextApp
2020
let appPort
2121
let buildId
2222
let requiredFilesManifest
23+
let errors = []
2324

2425
describe('Required Server Files', () => {
2526
beforeAll(async () => {
@@ -58,7 +59,8 @@ describe('Required Server Files', () => {
5859
try {
5960
await nextApp.getRequestHandler()(req, res)
6061
} catch (err) {
61-
console.error(err)
62+
console.error('top-level', err)
63+
errors.push(err)
6264
res.statusCode = 500
6365
res.end('error')
6466
}
@@ -419,4 +421,31 @@ describe('Required Server Files', () => {
419421
path: ['hello', 'world'],
420422
})
421423
})
424+
425+
it('should bubble error correctly for gip page', async () => {
426+
errors = []
427+
const res = await fetchViaHTTP(appPort, '/errors/gip', { crash: '1' })
428+
expect(res.status).toBe(500)
429+
expect(await res.text()).toBe('error')
430+
expect(errors.length).toBe(1)
431+
expect(errors[0].message).toContain('gip hit an oops')
432+
})
433+
434+
it('should bubble error correctly for gssp page', async () => {
435+
errors = []
436+
const res = await fetchViaHTTP(appPort, '/errors/gssp', { crash: '1' })
437+
expect(res.status).toBe(500)
438+
expect(await res.text()).toBe('error')
439+
expect(errors.length).toBe(1)
440+
expect(errors[0].message).toContain('gssp hit an oops')
441+
})
442+
443+
it('should bubble error correctly for gsp page', async () => {
444+
errors = []
445+
const res = await fetchViaHTTP(appPort, '/errors/gsp/crash')
446+
expect(res.status).toBe(500)
447+
expect(await res.text()).toBe('error')
448+
expect(errors.length).toBe(1)
449+
expect(errors[0].message).toContain('gsp hit an oops')
450+
})
422451
})

0 commit comments

Comments
 (0)
Please sign in to comment.