diff --git a/lib/error.js b/lib/error.js index f713ff78..dc405892 100644 --- a/lib/error.js +++ b/lib/error.js @@ -1,6 +1,5 @@ import React from 'react' import PropTypes from 'prop-types' -import exact from 'prop-types-exact' import HTTPStatus from 'http-status' import Head from './head' @@ -10,9 +9,9 @@ export default class Error extends React.Component { return { statusCode } } - static propTypes = exact({ + static propTypes = { statusCode: PropTypes.number - }) + } render () { const { statusCode } = this.props diff --git a/lib/router/router.js b/lib/router/router.js index b26433a8..1171ac36 100644 --- a/lib/router/router.js +++ b/lib/router/router.js @@ -299,19 +299,29 @@ export default class Router { cancelled = true } - const Component = await this.fetchRoute(route) + try { + const Component = await this.fetchRoute(route) - if (cancelled) { - const error = new Error(`Abort fetching component for route: "${route}"`) - error.cancelled = true - throw error + if (cancelled) { + const error = new Error(`Abort fetching component for route: "${route}"`) + error.cancelled = true + throw error + } + + if (cancel === this.componentLoadCancel) { + this.componentLoadCancel = null + } + + return Component + } catch (err) { + // There's an error in loading the route. + // Usually this happens when there's a failure in the webpack build + // So in that case, we need to load the page with full SSR + // That'll clean the invalid exising client side information. + // (Like cached routes) + window.location.href = as + throw err } - - if (cancel === this.componentLoadCancel) { - this.componentLoadCancel = null - } - - return Component } async getInitialProps (Component, ctx) { diff --git a/server/index.js b/server/index.js index 0be3b0c1..caaf707b 100644 --- a/server/index.js +++ b/server/index.js @@ -12,7 +12,6 @@ import { renderScriptError } from './render' import Router from './router' -import { resolveFromList } from './resolve' import { getAvailableChunks } from './utils' import getConfig from './config' // We need to go up one more level since we are in the `dist` directory @@ -190,7 +189,7 @@ export default class Server { return await renderScriptError(req, res, page, error, {}, this.renderOpts) } - const compilationErr = await this.getCompilationError(page, req, res) + const compilationErr = await this.getCompilationError() if (compilationErr) { const customFields = { statusCode: 500 } return await renderScriptError(req, res, page, compilationErr, customFields, this.renderOpts) @@ -273,7 +272,7 @@ export default class Server { async renderToHTML (req, res, pathname, query) { if (this.dev) { - const compilationErr = await this.getCompilationError(pathname) + const compilationErr = await this.getCompilationError() if (compilationErr) { res.statusCode = 500 return this.renderErrorToHTML(compilationErr, req, res, pathname, query) @@ -301,7 +300,7 @@ export default class Server { async renderErrorToHTML (err, req, res, pathname, query) { if (this.dev) { - const compilationErr = await this.getCompilationError('/_error') + const compilationErr = await this.getCompilationError() if (compilationErr) { res.statusCode = 500 return renderErrorToHTML(compilationErr, req, res, pathname, query, this.renderOpts) @@ -382,15 +381,14 @@ export default class Server { return true } - async getCompilationError (page, req, res) { + async getCompilationError () { if (!this.hotReloader) return const errors = await this.hotReloader.getCompilationErrors() if (!errors.size) return - const id = join(this.dir, this.dist, 'bundles', 'pages', page) - const p = resolveFromList(id, errors.keys()) - if (p) return errors.get(p)[0] + // Return the very first error we found. + return Array.from(errors.values())[0][0] } handleBuildHash (filename, hash, res) {