mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-06 12:52:31 +02:00
fix(core): ensure core error boundary is able to render theme layout (#9852)
This commit is contained in:
parent
60d9346965
commit
b26e262981
1 changed files with 30 additions and 12 deletions
|
@ -8,12 +8,13 @@
|
||||||
// Should we translate theme-fallback?
|
// Should we translate theme-fallback?
|
||||||
/* eslint-disable @docusaurus/no-untranslated-text */
|
/* eslint-disable @docusaurus/no-untranslated-text */
|
||||||
|
|
||||||
import React from 'react';
|
import React, {type ReactNode} from 'react';
|
||||||
import Head from '@docusaurus/Head';
|
import Head from '@docusaurus/Head';
|
||||||
import ErrorBoundary from '@docusaurus/ErrorBoundary';
|
import ErrorBoundary from '@docusaurus/ErrorBoundary';
|
||||||
import {getErrorCausalChain} from '@docusaurus/utils-common';
|
import {getErrorCausalChain} from '@docusaurus/utils-common';
|
||||||
import Layout from '@theme/Layout';
|
import Layout from '@theme/Layout';
|
||||||
import type {Props} from '@theme/Error';
|
import type {Props} from '@theme/Error';
|
||||||
|
import {RouteContextProvider} from '../../routeContext';
|
||||||
|
|
||||||
function ErrorDisplay({error, tryAgain}: Props): JSX.Element {
|
function ErrorDisplay({error, tryAgain}: Props): JSX.Element {
|
||||||
return (
|
return (
|
||||||
|
@ -54,21 +55,38 @@ function ErrorBoundaryError({error}: {error: Error}): JSX.Element {
|
||||||
return <p style={{whiteSpace: 'pre-wrap'}}>{fullMessage}</p>;
|
return <p style={{whiteSpace: 'pre-wrap'}}>{fullMessage}</p>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A bit hacky: we need to add an artificial RouteContextProvider here
|
||||||
|
// The goal is to be able to render the error inside the theme layout
|
||||||
|
// Without this, our theme classic would crash due to lack of route context
|
||||||
|
// See also https://github.com/facebook/docusaurus/pull/9852
|
||||||
|
function ErrorRouteContextProvider({children}: {children: ReactNode}) {
|
||||||
|
return (
|
||||||
|
<RouteContextProvider
|
||||||
|
value={{
|
||||||
|
plugin: {name: 'docusaurus-core-error-boundary', id: 'default'},
|
||||||
|
}}>
|
||||||
|
{children}
|
||||||
|
</RouteContextProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default function Error({error, tryAgain}: Props): JSX.Element {
|
export default function Error({error, tryAgain}: Props): JSX.Element {
|
||||||
// We wrap the error in its own error boundary because the layout can actually
|
// We wrap the error in its own error boundary because the layout can actually
|
||||||
// throw too... Only the ErrorDisplay component is simple enough to be
|
// throw too... Only the ErrorDisplay component is simple enough to be
|
||||||
// considered safe to never throw
|
// considered safe to never throw
|
||||||
return (
|
return (
|
||||||
<ErrorBoundary
|
<ErrorRouteContextProvider>
|
||||||
// Note: we display the original error here, not the error that we
|
<ErrorBoundary
|
||||||
// captured in this extra error boundary
|
// Note: we display the original error here, not the error that we
|
||||||
fallback={() => <ErrorDisplay error={error} tryAgain={tryAgain} />}>
|
// captured in this extra error boundary
|
||||||
<Head>
|
fallback={() => <ErrorDisplay error={error} tryAgain={tryAgain} />}>
|
||||||
<title>Page Error</title>
|
<Head>
|
||||||
</Head>
|
<title>Page Error</title>
|
||||||
<Layout>
|
</Head>
|
||||||
<ErrorDisplay error={error} tryAgain={tryAgain} />
|
<Layout>
|
||||||
</Layout>
|
<ErrorDisplay error={error} tryAgain={tryAgain} />
|
||||||
</ErrorBoundary>
|
</Layout>
|
||||||
|
</ErrorBoundary>
|
||||||
|
</ErrorRouteContextProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue