<commit_before>const Email = require("./email/Email");
const Request = require("./request/Request");
const HttpError = require("./error/HttpError");
const ForbiddenError = require("./error/ForbiddenError");
const JsonResponse = require("./response/JsonResponse");
const HtmlResponse = require("./response/HtmlResponse");
const RedirectResponse = require("./response/RedirectResponse");
const PlainTextResponse = require("./response/PlainTextResponse");
const logging = require("./lib/logging");

module.exports = (container) => async (event) => {
  const request = new Request(event, container.config.ENCRYPTION_KEY);

  let error;
  let response;

  try {
    const isValidRecaptcha = await container.isValidRecaptcha(request);

    if (!isValidRecaptcha) {
      throw new ForbiddenError("Form submission failed recaptcha");
    }

    error = request.validate(container.config.WHITELISTED_RECIPIENTS);

    if (error) {
      throw error;
    }

    const recipientCount = [].concat(
      request.recipients.cc,
      request.recipients.bcc,
      request.recipients.replyTo
    ).length;

    logging.info(
      `sending to '${request.recipients.to}' and ${recipientCount} other recipients`
    );

    const email = new Email(
      container.config.SENDER,
      container.config.SENDER_ARN,
      container.config.MSG_SUBJECT,
      request.recipients,
      request.body
    );

    error = email.validate();

    if (error) {
      throw error;
    }

    await container.sendEmail(email);

    const message = container.config.MSG_RECEIVE_SUCCESS;

    if (request.isJsonResponse()) {
      response = new JsonResponse(200, message);
    } else if (request.isRedirectResponse()) {
      response = new RedirectResponse(302, message, request.redirect);
    } else {
      try {
        response = new HtmlResponse(
          200,
          message,
          await container.loadTemplate()
        );
      } catch (error) {
        logging.error("unable to load template file", error);
        response = new PlainTextResponse(200, message);
      }
    }
  } catch (error) {
    logging.error("error was caught while executing receive lambda", error);

    let statusCode = 500;
    let message = "An unexpected error occurred";

    if (error instanceof HttpError) {
      statusCode = error.statusCode;
      message = error.message;
    }

    if (request.isJsonResponse()) {
      response = new JsonResponse(statusCode, message);
    } else {
      try {
        response = new HtmlResponse(
          statusCode,
          message,
          await container.loadTemplate()
        );
      } catch (error) {
        logging.error("unable to load template file", error);
        response = new PlainTextResponse(statusCode, message);
      }
    }
  }

  logging.info(`returning http ${response.statusCode} response`);

  return response.build();
};<commit_msg>split handler into smaller functions<commit_after>const Email = require("./email/Email");
const Request = require("./request/Request");
const HttpError = require("./error/HttpError");
const ForbiddenError = require("./error/ForbiddenError");
const JsonResponse = require("./response/JsonResponse");
const HtmlResponse = require("./response/HtmlResponse");
const RedirectResponse = require("./response/RedirectResponse");
const PlainTextResponse = require("./response/PlainTextResponse");
const logging = require("./lib/logging");

const validateRecaptcha = (recaptchaFn) => async (request) => {
  const isValid = await recaptchaFn(request);

  if (!isValid) {
    throw new ForbiddenError("Form submission failed recaptcha");
  }

  return request;
};

const validateRequest = (whitelist) => async (request) => {
  const error = request.validate(whitelist);

  if (error) {
    throw error;
  }

  return request;
};

const sendEmail = (sender, senderArn, subject, mailerFn) => async (request) => {
  const recipientCount = [].concat(
    request.recipients.cc,
    request.recipients.bcc,
    request.recipients.replyTo
  ).length;

  logging.info(
    `sending to '${request.recipients.to}' and ${recipientCount} other recipients`
  );

  const email = new Email(
    sender,
    senderArn,
    subject,
    request.recipients,
    request.body
  );

  const serviceError = email.validate();

  if (serviceError) {
    throw serviceError;
  }

  await mailerFn(email);

  return request;
};

const buildSuccessResponse = (message, templateFn) => async (request) => {
  if (request.isJsonResponse()) {
    return new JsonResponse(200, message);
  } else if (request.isRedirectResponse()) {
    return new RedirectResponse(302, message, request.redirect);
  } else {
    try {
      const template = await templateFn();
      return new HtmlResponse(200, message, template);
    } catch (error) {
      logging.error("unable to load template file", error);
      return new PlainTextResponse(200, message);
    }
  }
};

const buildErrorResponse = (isJsonResponse, templateFn) => async (error) => {
  logging.error("error was caught while executing receive lambda", error);

  let statusCode = 500;
  let message = "An unexpected error occurred";

  if (error instanceof HttpError) {
    statusCode = error.statusCode;
    message = error.message;
  }

  if (isJsonResponse) {
    return new JsonResponse(statusCode, message);
  } else {
    try {
      const template = await templateFn();
      return new HtmlResponse(statusCode, message, template);
    } catch (error) {
      logging.error("unable to load template file", error);
      return new PlainTextResponse(statusCode, message);
    }
  }
};

const handleResponse = async (response) => {
  logging.info(`returning http ${response.statusCode} response`);

  return response.build();
};

module.exports = (container) => async (event) => {
  const request = new Request(event, container.config.ENCRYPTION_KEY);

  return Promise.resolve()
    .then(validateRecaptcha(container.isValidRecaptcha))
    .then(validateRequest(container.config.WHITELISTED_RECIPIENTS))
    .then(
      sendEmail(
        container.config.SENDER,
        container.config.SENDER_ARN,
        container.config.MSG_SUBJECT,
        container.sendEmail
      )
    )
    .then(
      buildSuccessResponse(
        container.config.MSG_RECEIVE_SUCCESS,
        container.loadTemplate
      )
    )
    .catch(buildErrorResponse(request.isJsonResponse(), container.loadTemplate))
    .then(handleResponse);
};
{'fraction_non_alphanumeric': 0.1208534496184395, 'fraction_numerical': 0.004672169444011836, 'mean_word_length': 3.3245791245791247, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1723322', 'n_tokens_mistral': 1876, 'n_tokens_neox': 1803, 'n_words': 435}