Skip to content

Commit

Permalink
Add error handling for error being thrown in _app getinitialProps (#6680
Browse files Browse the repository at this point in the history
)

* Fix handling of undefined being thrown
in getInitialProps and update integration test

* Update test

* Move test to app-document
  • Loading branch information
ijjk committed Mar 17, 2019
1 parent 11a161f commit 87bd1c3
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 4 deletions.
4 changes: 3 additions & 1 deletion package.json
Expand Up @@ -10,7 +10,9 @@
"testonly": "jest",
"testall": "yarn check && yarn run testonly -- --coverage --forceExit --runInBand --reporters=default --reporters=jest-junit",
"pretest": "yarn run lint",
"test-take2": "git clean -d -x -e node_modules -e packages -f && yarn testall",
"git-reset": "git reset --hard HEAD",
"git-clean": "git clean -d -x -e node_modules -e packages -f",
"test-take2": "yarn git-reset && yarn git-clean && yarn testall",
"test": "yarn run testall || yarn run test-take2",
"coveralls": "cat ./test/coverage/lcov.info | coveralls",
"lint": "lerna run typescript && standard && standard --parser typescript-eslint-parser --plugin typescript packages/**/*.ts",
Expand Down
14 changes: 11 additions & 3 deletions packages/next-server/server/render.tsx
Expand Up @@ -235,7 +235,15 @@ export async function renderToHTML(
const asPath: string = req.url
const ctx = { err, req, res, pathname, query, asPath }
const router = new ServerRouter(pathname, query, asPath)
const props = await loadGetInitialProps(App, { Component, router, ctx })
let props: any

try {
props = await loadGetInitialProps(App, { Component, router, ctx })
} catch (err) {
if (!dev || !err) throw err
ctx.err = err
renderOpts.err = err
}

// the response might be finished on the getInitialProps call
if (isResSent(res)) return null
Expand All @@ -256,8 +264,8 @@ export async function renderToHTML(
? renderToStaticMarkup
: renderToString

if (err && ErrorDebug) {
return render(renderElementToString, <ErrorDebug error={err} />)
if (ctx.err && ErrorDebug) {
return render(renderElementToString, <ErrorDebug error={ctx.err} />)
}

if (dev && (props.router || props.Component)) {
Expand Down
1 change: 1 addition & 0 deletions test/integration/app-document/pages/_app.js
Expand Up @@ -27,6 +27,7 @@ class Layout extends React.Component {

export default class MyApp extends App {
static async getInitialProps ({ Component, router, ctx }) {
// throw _app GIP err here
let pageProps = {}

if (Component.getInitialProps) {
Expand Down
28 changes: 28 additions & 0 deletions test/integration/app-document/test/rendering.js
@@ -1,6 +1,8 @@
/* eslint-env jest */

import { join } from 'path'
import cheerio from 'cheerio'
import { check, File, waitFor } from 'next-test-utils'

export default function ({ app }, suiteName, render, fetch) {
async function get$ (path, query) {
Expand Down Expand Up @@ -102,6 +104,32 @@ export default function ({ app }, suiteName, render, fetch) {
const $ = await get$('/shared')
expect($('#currentstate').text() === 'UPDATED')
})

test('It should show valid error when thrown in _app getInitialProps', async () => {
const errMsg = 'have an error from _app getInitialProps'
const _app = new File(join(__dirname, '../pages/_app.js'))

let foundErr = false
expect(await render('/')).toMatch('page-index')
_app.replace('// throw _app GIP err here', `throw new Error("${errMsg}")`)

try {
let tries = 0
while (!foundErr && tries < 5) {
foundErr = (await render('/')).indexOf(errMsg) > -1
await waitFor(1000)
tries++
}
} finally {
_app.restore()
// Make sure _app is restored
await check(
() => render('/'),
/page-index/
)
expect(foundErr).toBeTruthy()
}
})
})
})
}

0 comments on commit 87bd1c3

Please sign in to comment.