import React, { useState } from 'react';
import { ErrorBoundary as ReactErrorBoundary } from 'react-error-boundary';
import PropTypes from 'prop-types';
import { useTranslation } from 'react-i18next';
import i18n from 'i18next';
import Modal from '../Modal';
import Icon from '../Icon';
import IconButton from '../IconButton';
const isProduction = process.env.NODE_ENV === 'production';
const DefaultFallback = ({ error, context, resetErrorBoundary, fallbackRoute }) => {
const { t } = useTranslation('ErrorBoundary');
const [showDetails, setShowDetails] = useState(false);
const title = `${t('Something went wrong')}${!isProduction && ` ${t('in')} ${context}`}.`;
const subtitle = t('Sorry, something went wrong there. Try again.');
return (
{title}
{subtitle}
{!isProduction && (
{t('Context')}: {context}
{t('Error Message')}: {error.message}
setShowDetails(!showDetails)}
>
{t('Stack Trace')}
{showDetails &&
Stack: {error.stack}
}
)}
);
};
const noop = () => {};
DefaultFallback.propTypes = {
error: PropTypes.object.isRequired,
resetErrorBoundary: PropTypes.func,
componentStack: PropTypes.string,
};
DefaultFallback.defaultProps = {
resetErrorBoundary: noop,
};
const ErrorBoundary = ({
context,
onReset,
onError,
fallbackComponent: FallbackComponent,
children,
fallbackRoute,
isPage,
}) => {
const [isOpen, setIsOpen] = useState(true);
const onErrorHandler = (error, componentStack) => {
console.error(`${context} Error Boundary`, error, componentStack, context);
onError(error, componentStack, context);
};
const onResetHandler = (...args) => onReset(...args);
const withModal = Component => props => (
{
setIsOpen(false);
if (fallbackRoute && typeof window !== 'undefined') {
window.location = fallbackRoute;
}
}}
>
);
const Fallback = isPage ? FallbackComponent : withModal(FallbackComponent);
return (
(
)}
onReset={onResetHandler}
onError={onErrorHandler}
>
{children}
);
};
ErrorBoundary.propTypes = {
context: PropTypes.string,
onReset: PropTypes.func,
onError: PropTypes.func,
fallbackComponent: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
children: PropTypes.node.isRequired,
fallbackRoute: PropTypes.string,
};
ErrorBoundary.defaultProps = {
context: 'OHIF',
onReset: noop,
onError: noop,
fallbackComponent: DefaultFallback,
fallbackRoute: null,
};
export default ErrorBoundary;