import * as React from 'react';

export interface Props {
  message?: string;
}
export interface State {
  hasError: boolean;
}

/**
 * This component prevents errors from bubbling up to the component tree.
 * The effect is to limit the damage caused by an error. It is also be
 * helpful in narrowing down the source of the error.
 *
 * Usage:
 * <ErrorBoundary>
 *     <SomeComponent />
 * </ErrorBoundary>
 */
export class ErrorBoundary extends React.Component<Props, State> {
  static defaultProps: Props = {
    message: 'Something broke.',
  };

  constructor(props) {
    super(props);
    this.state = {
      hasError: false,
    };
  }

  static getDerivedStateFromError() {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // You can also log the error to an error reporting service
    console.log(error);
    console.log(errorInfo);
    this.setState({ hasError: true });
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <div>{this.props.message}</div>;
    }

    return this.props.children;
  }
}
