# All files / src withErrorBoundary.tsx

0% Statements 0/21
0% Branches 0/15
0% Functions 0/6
0% Lines 0/19

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62

     import _isEqual = require('lodash/isEqual');
    import * as React from 'react';

    const FallbackComponent: FallbackComponent = ({ error }) => {
      return (
        <div className="p-4">
          <b>Error</b>
          {error && `: ${error.message}`}
        </div>
      );
    };

    export type FallbackComponent = React.ComponentType<{ error: Error | null }>;
    export interface IErrorBoundary {
      FallbackComponent?: FallbackComponent;
    }

    // react-error-boundary does not support recovering, see  https://github.com/bvaughn/react-error-boundary/pull/16/files
    export function withErrorBoundary<T extends IErrorBoundary>(
      WrappedComponent: React.ComponentType<Omit<T, 'FallbackComponent'>>,
      props?: Array<keyof T>,
      displayName?: string,
    ) {
      return class ErrorBoundary extends React.PureComponent<T, { error: Error | null }> {
        public state = {
          error: null,
        };

        public static displayName = displayName;

        public componentDidUpdate(prevProps: Readonly<T>) {
          if (this.state.error !== null) {
            if (!props || !props.length) {
              if (!_isEqual(this.props, prevProps)) {
                this.setState({ error: null });
              }
            } else {
              for (const prop of props) {
                if (!_isEqual(this.props[prop], prevProps[prop])) {
                  this.setState({ error: null });
                }
              }
            }
          }
        }

        // there is no error hook yet, see https://reactjs.org/docs/hooks-faq.html#how-do-lifecycle-methods-correspond-to-hooks
        public static getDerivedStateFromError(error: Error) {
          return { error };
        }

        public render() {
          const { FallbackComponent: Fallback = FallbackComponent, ...props } = this.props;
          if (this.state.error) {
            return <Fallback error={this.state.error} />;
          }

          return <WrappedComponent {...props} />;
        }
      };
    }