diff --git a/packages/next/client/app-index.tsx b/packages/next/client/app-index.tsx index f9dc21c51b5b4..09d024418ac13 100644 --- a/packages/next/client/app-index.tsx +++ b/packages/next/client/app-index.tsx @@ -7,7 +7,7 @@ import { createFromReadableStream } from 'next/dist/compiled/react-server-dom-we import { HeadManagerContext } from '../shared/lib/head-manager-context' import { GlobalLayoutRouterContext } from '../shared/lib/app-router-context' -import { NEXT_DYNAMIC_NO_SSR_CODE } from '../shared/lib/no-ssr-error' +import onRecoverableError from './on-recoverable-error' /// @@ -130,23 +130,6 @@ if (document.readyState === 'loading') { DOMContentLoaded() } -function onRecoverableError(err: any) { - // Using default react onRecoverableError - // x-ref: https://github.com/facebook/react/blob/d4bc16a7d69eb2ea38a88c8ac0b461d5f72cdcab/packages/react-dom/src/client/ReactDOMRoot.js#L83 - const defaultOnRecoverableError = - typeof reportError === 'function' - ? // In modern browsers, reportError will dispatch an error event, - // emulating an uncaught JavaScript error. - reportError - : (error: any) => { - window.console.error(error) - } - - // Skip certain custom errors which are not expected to be reported on client - if (err.digest === NEXT_DYNAMIC_NO_SSR_CODE) return - defaultOnRecoverableError(err) -} - const nextServerDataLoadingGlobal = ((self as any).__next_f = (self as any).__next_f || []) nextServerDataLoadingGlobal.forEach(nextServerDataCallback) diff --git a/packages/next/client/index.tsx b/packages/next/client/index.tsx index 66bb9a6b88eb9..bd35576b64db1 100644 --- a/packages/next/client/index.tsx +++ b/packages/next/client/index.tsx @@ -43,7 +43,7 @@ import { PathnameContextProviderAdapter, } from '../shared/lib/router/adapters' import { SearchParamsContext } from '../shared/lib/hooks-client-context' -import { NEXT_DYNAMIC_NO_SSR_CODE } from '../shared/lib/no-ssr-error' +import onRecoverableError from './on-recoverable-error' /// @@ -507,11 +507,7 @@ function renderReactElement( if (!reactRoot) { // Unlike with createRoot, you don't need a separate root.render() call here reactRoot = ReactDOM.hydrateRoot(domEl, reactEl, { - onRecoverableError(err: any) { - // Skip certain custom errors which are not expected to throw on client - if (err.message === NEXT_DYNAMIC_NO_SSR_CODE) return - throw err - }, + onRecoverableError, }) // TODO: Remove shouldHydrate variable when React 18 is stable as it can depend on `reactRoot` existing shouldHydrate = false diff --git a/packages/next/client/on-recoverable-error.ts b/packages/next/client/on-recoverable-error.ts new file mode 100644 index 0000000000000..0a1d7d0f789aa --- /dev/null +++ b/packages/next/client/on-recoverable-error.ts @@ -0,0 +1,18 @@ +import { NEXT_DYNAMIC_NO_SSR_CODE } from '../shared/lib/no-ssr-error' + +export default function onRecoverableError(err: any) { + // Using default react onRecoverableError + // x-ref: https://github.com/facebook/react/blob/d4bc16a7d69eb2ea38a88c8ac0b461d5f72cdcab/packages/react-dom/src/client/ReactDOMRoot.js#L83 + const defaultOnRecoverableError = + typeof reportError === 'function' + ? // In modern browsers, reportError will dispatch an error event, + // emulating an uncaught JavaScript error. + reportError + : (error: any) => { + window.console.error(error) + } + + // Skip certain custom errors which are not expected to be reported on client + if (err.digest === NEXT_DYNAMIC_NO_SSR_CODE) return + defaultOnRecoverableError(err) +}