@docusaurus/core
Version:
Easy to Maintain Open Source Documentation Websites
75 lines (74 loc) • 2.81 kB
JavaScript
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// Should we translate theme-fallback?
/* eslint-disable @docusaurus/no-untranslated-text */
import React from 'react';
import Head from '@docusaurus/Head';
import ErrorBoundary from '@docusaurus/ErrorBoundary';
import { getErrorCausalChain } from '@docusaurus/utils-common';
import Layout from '@theme/Layout';
import { RouteContextProvider } from '../../routeContext';
function ErrorDisplay({ error, tryAgain }) {
return (<div style={{
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'flex-start',
minHeight: '100vh',
width: '100%',
maxWidth: '80ch',
fontSize: '20px',
margin: '0 auto',
padding: '1rem',
}}>
<h1 style={{ fontSize: '3rem' }}>This page crashed</h1>
<button type="button" onClick={tryAgain} style={{
margin: '1rem 0',
fontSize: '2rem',
cursor: 'pointer',
borderRadius: 20,
padding: '1rem',
}}>
Try again
</button>
<ErrorBoundaryError error={error}/>
</div>);
}
function ErrorBoundaryError({ error }) {
const causalChain = getErrorCausalChain(error);
const fullMessage = causalChain.map((e) => e.message).join('\n\nCause:\n');
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 }) {
return (<RouteContextProvider value={{
plugin: { name: 'docusaurus-core-error-boundary', id: 'default' },
}}>
{children}
</RouteContextProvider>);
}
export default function Error({ error, tryAgain }) {
// 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
// considered safe to never throw
return (<ErrorRouteContextProvider>
<ErrorBoundary
// Note: we display the original error here, not the error that we
// captured in this extra error boundary
fallback={() => <ErrorDisplay error={error} tryAgain={tryAgain}/>}>
<Head>
<title>Page Error</title>
</Head>
<Layout>
<ErrorDisplay error={error} tryAgain={tryAgain}/>
</Layout>
</ErrorBoundary>
</ErrorRouteContextProvider>);
}