export async function httpPostToCognitoWithRetry()

in src/lambda-edge/shared/shared.ts [495:548]


export async function httpPostToCognitoWithRetry(
  url: string,
  data: Buffer,
  options: RequestOptions,
  logger: Logger
) {
  let attempts = 0;
  while (true) {
    ++attempts;
    try {
      return await fetch(url, data, {
        agent: AGENT,
        ...options,
        method: "POST",
      }).then((res) => {
        if (res.status !== 200) {
          throw new Error(`Status is ${res.status}, expected 200`);
        }
        if (!res.headers["content-type"]?.startsWith("application/json")) {
          throw new Error(
            `Content-Type is ${res.headers["content-type"]}, expected application/json`
          );
        }
        return {
          ...res,
          data: JSON.parse(res.data.toString()),
        };
      });
    } catch (err) {
      logger.debug(`HTTP POST to ${url} failed (attempt ${attempts}):`);
      logger.debug(err);
      if (attempts >= 5) {
        // Try 5 times at most
        logger.error(
          `No success after ${attempts} attempts, seizing further attempts`
        );
        throw err;
      }
      if (attempts >= 2) {
        // After attempting twice immediately, do some exponential backoff with jitter
        logger.debug(
          "Doing exponential backoff with jitter, before attempting HTTP POST again ..."
        );
        await new Promise((resolve) =>
          setTimeout(
            resolve,
            25 * (Math.pow(2, attempts) + Math.random() * attempts)
          )
        );
        logger.debug("Done waiting, will try HTTP POST again now");
      }
    }
  }
}