From 4d68044eab95d14fd190477ab096a91188f1090e Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sun, 26 Jun 2022 22:48:13 -0400 Subject: [PATCH 1/3] fix: made _devPagesManifest.json loading resilient to failures --- packages/next/client/page-loader.ts | 29 ++++++++++------------- packages/next/shared/lib/router/router.ts | 2 +- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/packages/next/client/page-loader.ts b/packages/next/client/page-loader.ts index 62a06a19cf09..e1224b7e0a55 100644 --- a/packages/next/client/page-loader.ts +++ b/packages/next/client/page-loader.ts @@ -75,23 +75,18 @@ export default class PageLoader { if (window.__DEV_PAGES_MANIFEST) { return window.__DEV_PAGES_MANIFEST.pages } else { - if (!this.promisedDevPagesManifest) { - // TODO: Decide what should happen when fetching fails instead of asserting - // @ts-ignore - this.promisedDevPagesManifest = fetch( - `${this.assetPrefix}/_next/static/development/_devPagesManifest.json` - ) - .then((res) => res.json()) - .then((manifest: { pages: string[] }) => { - window.__DEV_PAGES_MANIFEST = manifest - return manifest.pages - }) - .catch((err) => { - console.log(`Failed to fetch devPagesManifest`, err) - }) - } - // TODO Remove this assertion as this could be undefined - return this.promisedDevPagesManifest! + this.promisedDevPagesManifest ||= fetch( + `${this.assetPrefix}/_next/static/development/_devPagesManifest.json` + ) + .then((res) => res.json()) + .then((manifest: { pages: string[] }) => { + window.__DEV_PAGES_MANIFEST = manifest + return manifest.pages + }) + .catch((err) => { + throw new Error(`Failed to fetch devPagesManifest: ${err}`) + }) + return this.promisedDevPagesManifest } } } diff --git a/packages/next/shared/lib/router/router.ts b/packages/next/shared/lib/router/router.ts index d0e7be8c678f..2930a47cbbdf 100644 --- a/packages/next/shared/lib/router/router.ts +++ b/packages/next/shared/lib/router/router.ts @@ -1092,7 +1092,7 @@ export default class Router implements BaseRouter { // The build manifest needs to be loaded before auto-static dynamic pages // get their query parameters to allow ensuring they can be parsed properly // when rewritten to - let pages: any, rewrites: any + let pages: string[], rewrites: any try { ;[pages, { __rewrites: rewrites }] = await Promise.all([ this.pageLoader.getPageList(), From d27ff1b4189c82995a95951643038a627b818c38 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sun, 26 Jun 2022 23:31:49 -0400 Subject: [PATCH 2/3] On second thought, make it even more verbose --- packages/next/client/page-loader.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/next/client/page-loader.ts b/packages/next/client/page-loader.ts index e1224b7e0a55..5a0b98745bae 100644 --- a/packages/next/client/page-loader.ts +++ b/packages/next/client/page-loader.ts @@ -84,7 +84,10 @@ export default class PageLoader { return manifest.pages }) .catch((err) => { - throw new Error(`Failed to fetch devPagesManifest: ${err}`) + console.log(`Failed to fetch devPagesManifest:`, err) + throw new Error( + `Failed to fetch _devPagesManifest.json. Is something blocking that network request?` + ) }) return this.promisedDevPagesManifest } From be68a96c823ca5971036c8751e0b967202da9475 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sun, 7 Aug 2022 13:44:41 -0400 Subject: [PATCH 3/3] Added error message description page --- errors/failed-to-fetch-devpagesmanifest.md | 18 ++++++++++++++++++ errors/manifest.json | 4 ++++ packages/next/client/page-loader.ts | 3 ++- 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 errors/failed-to-fetch-devpagesmanifest.md diff --git a/errors/failed-to-fetch-devpagesmanifest.md b/errors/failed-to-fetch-devpagesmanifest.md new file mode 100644 index 000000000000..3a19a0879e71 --- /dev/null +++ b/errors/failed-to-fetch-devpagesmanifest.md @@ -0,0 +1,18 @@ +# Failed to fetch devPagesManifest + +#### Why This Error Occurred + +The network request to load `_devPagesManifest.json` did not succeed. + +The dev pages manifest file is used by `next/link` to retrieve the list of pages to be (pre-)loaded by Next.js. +If it fails, Next.js cannot properly navigate and link between pages. + +#### Possible Ways to Fix It + +- Make sure your browser developer tools, extensions, and any other network tools aren't blocking that request. +- If you're running your Next.js application through a proxy, nginx, or other network layer, make sure links like `/_next/*` are configured to be allowed. + +### Useful Links + +- [Original GitHub Issue Thread](https://github.com/vercel/next.js/issues/16874) +- [GitHub Issue Thread With Reproduction](https://github.com/vercel/next.js/issues/38047) diff --git a/errors/manifest.json b/errors/manifest.json index 8e5375a6d5a1..123a6d45b306 100644 --- a/errors/manifest.json +++ b/errors/manifest.json @@ -661,6 +661,10 @@ { "title": "invalid-script", "path": "/errors/invalid-script.md" + }, + { + "title": "failed-to-fetch-devpagesmanifest", + "path": "/errors/failed-to-fetch-devpagesmanifest.md" } ] } diff --git a/packages/next/client/page-loader.ts b/packages/next/client/page-loader.ts index 5a0b98745bae..cbe6e8461549 100644 --- a/packages/next/client/page-loader.ts +++ b/packages/next/client/page-loader.ts @@ -86,7 +86,8 @@ export default class PageLoader { .catch((err) => { console.log(`Failed to fetch devPagesManifest:`, err) throw new Error( - `Failed to fetch _devPagesManifest.json. Is something blocking that network request?` + `Failed to fetch _devPagesManifest.json. Is something blocking that network request?\n` + + 'Read more: https://nextjs.org/docs/messages/failed-to-fetch-devpagesmanifest' ) }) return this.promisedDevPagesManifest