import React, { useState } from 'react'; import { ErrorBoundary as ReactErrorBoundary } from 'react-error-boundary'; import PropTypes from 'prop-types'; 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 [showDetails, setShowDetails] = useState(false); const title = `Something went wrong${!isProduction && ` in ${context}`}.`; const subtitle = `Sorry, something went wrong there. Try again.`; return (

{title}

{subtitle}

{!isProduction && (

Context: {context}

Error Message: {error.message}

setShowDetails(!showDetails)} >
{'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;