--- /dev/null
+import React from 'react';
+import PropTypes from 'prop-types';
+import illustration from '../../images/elephant_ui_disappointed.svg';
+
+export default class ErrorBoundary extends React.PureComponent {
+
+ static propTypes = {
+ children: PropTypes.node,
+ };
+
+ state = {
+ hasError: false,
+ stackTrace: undefined,
+ componentStack: undefined,
+ }
+
+ componentDidCatch(error, info) {
+ this.setState({
+ hasError: true,
+ stackTrace: error.stack,
+ componentStack: info && info.componentStack,
+ });
+ }
+
+ render() {
+ const { hasError } = this.state;
+
+ if (!hasError) {
+ return this.props.children;
+ }
+
+ return (
+ <div>
+ <img src={illustration} alt='' />
+ </div>
+ );
+ }
+
+}
import { IntlProvider, addLocaleData } from 'react-intl';
import { getLocale } from '../locales';
import initialState from '../initial_state';
+import ErrorBoundary from '../components/error_boundary';
const { localeData, messages } = getLocale();
addLocaleData(localeData);
return (
<IntlProvider locale={locale} messages={messages}>
<Provider store={store}>
- <MastodonMount />
+ <ErrorBoundary>
+ <MastodonMount />
+ </ErrorBoundary>
</Provider>
</IntlProvider>
);
const { fetchComponent, onFetch, onFetchSuccess, onFetchFail, renderDelay } = props || this.props;
const cachedMod = Bundle.cache.get(fetchComponent);
+ if (fetchComponent === undefined) {
+ this.setState({ mod: null });
+ return Promise.resolve();
+ }
+
onFetch();
if (cachedMod) {