diff --git a/packages/next/client/link.tsx b/packages/next/client/link.tsx index d45531791a95f30..9f846681accb0d1 100644 --- a/packages/next/client/link.tsx +++ b/packages/next/client/link.tsx @@ -209,7 +209,15 @@ class Link extends Component { if (!this.p || typeof window === 'undefined') return // Prefetch the JSON page if asked (only in the client) const [href, asPath] = this.getPaths() - Router.prefetch(href, asPath, options) + // We need to handle a prefetch error here since we may be + // loading with priority which can reject but we don't + // want to force navigation since this is only a prefetch + Router.prefetch(href, asPath, options).catch(err => { + if (process.env.NODE_ENV !== 'production') { + // rethrow to show invalid URL errors + throw err + } + }) prefetched[href] = true } diff --git a/test/integration/preload-viewport/pages/invalid-prefetch.js b/test/integration/preload-viewport/pages/invalid-prefetch.js new file mode 100644 index 000000000000000..a01f7638d841d1e --- /dev/null +++ b/test/integration/preload-viewport/pages/invalid-prefetch.js @@ -0,0 +1,9 @@ +import Link from 'next/link' + +export default () => ( + <> + + I'm broken... + + +) diff --git a/test/integration/preload-viewport/test/index.test.js b/test/integration/preload-viewport/test/index.test.js index 81b035e2dbe8541..0df30ea2464f50e 100644 --- a/test/integration/preload-viewport/test/index.test.js +++ b/test/integration/preload-viewport/test/index.test.js @@ -163,6 +163,21 @@ describe('Prefetching Links in viewport', () => { } }) + it('should not have unhandledRejection when failing to prefetch on link', async () => { + const browser = await webdriver(appPort, '/') + await browser.eval(`(function() { + window.addEventListener('unhandledrejection', function (err) { + window.hadUnhandledReject = true; + }) + window.next.router.push('/invalid-prefetch'); + })()`) + + expect(await browser.eval('window.hadUnhandledReject')).toBeFalsy() + + await browser.elementByCss('#invalid-link').moveTo() + expect(await browser.eval('window.hadUnhandledReject')).toBeFalsy() + }) + it('should not prefetch when prefetch is explicitly set to false', async () => { const browser = await webdriver(appPort, '/opt-out')