From 963585a4fcbc7af68dae759a96936f9973d861c2 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sun, 7 Aug 2022 15:36:03 -0400 Subject: [PATCH] fix: improve logging for _devPagesManifest.json loading failures (#38046) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Bug - [x] Fixes #38047 - ~[ ] Integration tests added: do you want them added for such an unusual edge case?~ [Comment below: skipping](https://github.com/vercel/next.js/pull/38046#issuecomment-1207444526) - [x] Errors have helpful link attached, see `contributing.md`: ~I'll wait until this approach & error message are confirmed before thinking more deeply on how to explain the error~ Sending a draft PR as reference ahead of time. 🙂 Doesn't resolve the root issue of why `_devPagesManifest.json` might fail to load. But does improve the log for when it happens. I'd suggest applying this same fix to `_devMiddlewareManifest.json` too.
Before After
Console

Failed to fetch devPagesManifest TypeError: Failed to fetch
    at PageLoader.getPageList (page-loader.js?e87a:30:53)
    at _callee$ (router.js?8684:955:45)
    at ...


router.js?8684:1319 Uncaught (in promise) TypeError: Cannot \
read properties of undefined (reading 'includes')
    at resolveDynamicRoute (router.js?8684:1319:16)
    at _callee$
    at ...


Failed to fetch devPagesManifest: TypeError: Failed to fetch
    at PageLoader.getPageList (page-loader.js?e87a:30:53)
    at _callee$ (router.js?8684:955:45)
    at ...

Visual Screenshot of a Next.js runtime error: TypeError: Cannot read properties of undefined (reading 'includes') Screenshot of a Next.js runtime error: Error: Failed to fetch _devPagesManifest.json. Is something blocking that network request?
--- errors/failed-to-fetch-devpagesmanifest.md | 18 ++++++++++++ errors/manifest.json | 4 +++ packages/next/client/page-loader.ts | 33 +++++++++++----------- 3 files changed, 38 insertions(+), 17 deletions(-) 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 9bc09eebbd1b..199d52a52bac 100644 --- a/errors/manifest.json +++ b/errors/manifest.json @@ -715,6 +715,10 @@ { "title": "invalid-next-config", "path": "/errors/invalid-next-config.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 22e6963c4588..5599b3106de4 100644 --- a/packages/next/client/page-loader.ts +++ b/packages/next/client/page-loader.ts @@ -58,23 +58,22 @@ 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) => { + console.log(`Failed to fetch devPagesManifest:`, err) + throw new Error( + `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 } } }