export function withErrorHandler()

in src/amo/errorHandler.js [111:174]


export function withErrorHandler({ name, id, extractId = null }) {
  if (id && extractId) {
    throw new Error('You can define either `id` or `extractId` but not both.');
  }

  if (extractId && typeof extractId !== 'function') {
    throw new Error(
      '`extractId` must be a function taking `ownProps` as unique argument.',
    );
  }

  return (WrappedComponent) => {
    const mapStateToProps = () => {
      let defaultErrorId;

      if (!extractId) {
        // Each component instance gets its own error handler ID.
        defaultErrorId = id;

        if (!defaultErrorId) {
          defaultErrorId = generateHandlerId({ name });
          log.debug(`Generated error handler ID: ${defaultErrorId}`);
        }
      }

      // Now that the component has been instantiated, return its state mapper
      // function.
      return (state, ownProps) => {
        if (extractId) {
          defaultErrorId = `${name}-${extractId(ownProps)}`;
          log.debug(oneLine`Generated error handler ID with extractId():
            ${defaultErrorId}`);
        }

        const errorId = ownProps.errorHandler
          ? ownProps.errorHandler.id
          : defaultErrorId;

        return {
          error: state.errors[errorId],
          errorId,
        };
      };
    };

    const mergeProps = (stateProps, dispatchProps, ownProps) => {
      const errorHandler =
        ownProps.errorHandler ||
        new ErrorHandler({
          id: stateProps.errorId,
        });
      errorHandler.setDispatch(dispatchProps.dispatch);
      if (stateProps.error) {
        errorHandler.captureError(stateProps.error);
      }

      return { ...ownProps, errorHandler };
    };

    return compose(connect(mapStateToProps, undefined, mergeProps))(
      WrappedComponent,
    );
  };
}