@@ -9,7 +9,6 @@ import React from 'react'
9
9
import { UrlWithParsedQuery } from 'url'
10
10
import Watchpack from 'watchpack'
11
11
import { ampValidation } from '../build/output/index'
12
- import * as Log from '../build/output/log'
13
12
import { PUBLIC_DIR_MIDDLEWARE_CONFLICT } from '../lib/constants'
14
13
import { fileExists } from '../lib/file-exists'
15
14
import { findPagesDir } from '../lib/find-pages-dir'
@@ -19,7 +18,6 @@ import {
19
18
PHASE_DEVELOPMENT_SERVER ,
20
19
CLIENT_STATIC_FILES_PATH ,
21
20
DEV_CLIENT_PAGES_MANIFEST ,
22
- STATIC_STATUS_PAGES ,
23
21
} from '../next-server/lib/constants'
24
22
import {
25
23
getRouteMatcher ,
@@ -28,7 +26,11 @@ import {
28
26
isDynamicRoute ,
29
27
} from '../next-server/lib/router/utils'
30
28
import { __ApiPreviewProps } from '../next-server/server/api-utils'
31
- import Server , { ServerConstructor } from '../next-server/server/next-server'
29
+ import Server , {
30
+ WrappedBuildError ,
31
+ ServerConstructor ,
32
+ FindComponentsResult ,
33
+ } from '../next-server/server/next-server'
32
34
import { normalizePagePath } from '../next-server/server/normalize-page-path'
33
35
import Router , { Params , route } from '../next-server/server/router'
34
36
import { eventCliSession } from '../telemetry/events'
@@ -39,6 +41,11 @@ import { findPageFile } from './lib/find-page-file'
39
41
import { getNodeOptionsWithoutInspect } from './lib/utils'
40
42
import { withCoalescedInvoke } from '../lib/coalesced-function'
41
43
import { NextConfig } from '../next-server/server/config'
44
+ import { ParsedUrlQuery } from 'querystring'
45
+ import {
46
+ LoadComponentsReturnType ,
47
+ loadDefaultErrorComponents ,
48
+ } from '../next-server/server/load-components'
42
49
43
50
if ( typeof React . Suspense === 'undefined' ) {
44
51
throw new Error (
@@ -600,95 +607,34 @@ export default class DevServer extends Server {
600
607
return this . hotReloader ! . ensurePage ( pathname )
601
608
}
602
609
603
- async renderToHTML (
604
- req : IncomingMessage ,
605
- res : ServerResponse ,
610
+ protected async findPageComponents (
606
611
pathname : string ,
607
- query : { [ key : string ] : string }
608
- ) : Promise < string | null > {
612
+ query : ParsedUrlQuery = { } ,
613
+ params : Params | null = null
614
+ ) : Promise < FindComponentsResult | null > {
609
615
await this . devReady
610
616
const compilationErr = await this . getCompilationError ( pathname )
611
617
if ( compilationErr ) {
612
- res . statusCode = 500
613
- return this . renderErrorToHTML ( compilationErr , req , res , pathname , query )
618
+ // Wrap build errors so that they don't get logged again
619
+ throw new WrappedBuildError ( compilationErr )
614
620
}
615
-
616
- // In dev mode we use on demand entries to compile the page before rendering
617
621
try {
618
- await this . hotReloader ! . ensurePage ( pathname ) . catch ( async ( err : Error ) => {
619
- if ( ( err as any ) . code !== 'ENOENT' ) {
620
- throw err
621
- }
622
-
623
- for ( const dynamicRoute of this . dynamicRoutes || [ ] ) {
624
- const params = dynamicRoute . match ( pathname )
625
- if ( ! params ) {
626
- continue
627
- }
628
-
629
- return this . hotReloader ! . ensurePage ( dynamicRoute . page )
630
- }
631
- throw err
632
- } )
622
+ await this . hotReloader ! . ensurePage ( pathname )
623
+ return super . findPageComponents ( pathname , query , params )
633
624
} catch ( err ) {
634
- if ( err . code === 'ENOENT' ) {
635
- try {
636
- await this . hotReloader ! . ensurePage ( '/404' )
637
- } catch ( hotReloaderError ) {
638
- if ( hotReloaderError . code !== 'ENOENT' ) {
639
- throw hotReloaderError
640
- }
641
- }
642
-
643
- res . statusCode = 404
644
- return this . renderErrorToHTML ( null , req , res , pathname , query )
625
+ if ( ( err as any ) . code !== 'ENOENT' ) {
626
+ throw err
645
627
}
646
- if ( ! this . quiet ) console . error ( err )
628
+ return null
647
629
}
648
- const html = await super . renderToHTML ( req , res , pathname , query )
649
- return html
650
630
}
651
631
652
- async renderErrorToHTML (
653
- err : Error | null ,
654
- req : IncomingMessage ,
655
- res : ServerResponse ,
656
- pathname : string ,
657
- query : { [ key : string ] : string }
658
- ) : Promise < string | null > {
659
- await this . devReady
660
- if ( res . statusCode === 404 && ( await this . hasPage ( '/404' ) ) ) {
661
- await this . hotReloader ! . ensurePage ( '/404' )
662
- } else if (
663
- STATIC_STATUS_PAGES . includes ( `/${ res . statusCode } ` ) &&
664
- ( await this . hasPage ( `/${ res . statusCode } ` ) )
665
- ) {
666
- await this . hotReloader ! . ensurePage ( `/${ res . statusCode } ` )
667
- } else {
668
- await this . hotReloader ! . ensurePage ( '/_error' )
669
- }
670
-
671
- const compilationErr = await this . getCompilationError ( pathname )
672
- if ( compilationErr ) {
673
- res . statusCode = 500
674
- return super . renderErrorToHTML ( compilationErr , req , res , pathname , query )
675
- }
676
-
677
- if ( ! err && res . statusCode === 500 ) {
678
- err = new Error (
679
- 'An undefined error was thrown sometime during render... ' +
680
- 'See https://nextjs.org/docs/messages/threw-undefined'
681
- )
682
- }
683
-
684
- try {
685
- const out = await super . renderErrorToHTML ( err , req , res , pathname , query )
686
- return out
687
- } catch ( err2 ) {
688
- if ( ! this . quiet ) Log . error ( err2 )
689
- res . statusCode = 500
690
- return super . renderErrorToHTML ( err2 , req , res , pathname , query )
691
- }
632
+ protected async getFallbackErrorComponents ( ) : Promise < LoadComponentsReturnType | null > {
633
+ await this . hotReloader ! . buildFallbackError ( )
634
+ // Build the error page to ensure the fallback is built too.
635
+ // TODO: See if this can be moved into hotReloader or removed.
636
+ await this . hotReloader ! . ensurePage ( '/_error' )
637
+ return await loadDefaultErrorComponents ( this . distDir )
692
638
}
693
639
694
640
sendHTML (
0 commit comments