/** * External dependencies */ import { Component, ReactNode, ErrorInfo } from 'react'; import { __ } from '@wordpress/i18n'; import { Button } from '@wordpress/components'; /** * Internal dependencies */ import './style.scss'; type ErrorBoundaryProps = { children: ReactNode; }; type ErrorBoundaryState = { hasError: boolean; error: Error | null; errorInfo: ErrorInfo | null; }; export class ErrorBoundary extends Component< ErrorBoundaryProps, ErrorBoundaryState > { constructor( props: ErrorBoundaryProps ) { super( props ); this.state = { hasError: false, error: null, errorInfo: null }; } static getDerivedStateFromError( error: Error ): Partial< ErrorBoundaryState > { return { hasError: true, error }; } componentDidCatch( _error: Error, errorInfo: ErrorInfo ) { this.setState( { errorInfo } ); // TODO: Log error to error tracking service } handleRefresh = () => { window.location.reload(); }; handleOpenSupport = () => { window.open( 'https://wordpress.org/support/plugin/woocommerce/', '_blank' ); }; render() { if ( this.state.hasError ) { return (

{ __( 'Oops, something went wrong', 'woocommerce' ) }

{ __( "We're sorry for the inconvenience. Please try reloading the page, or you can get support from the community forums.", 'woocommerce' ) }

{ __( 'Click for error details', 'woocommerce' ) }
{ this.state.error && this.state.error.toString() }

{ this.state.errorInfo && this.state.errorInfo.componentStack }

); } return this.props.children; } }