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");
}
}
}
}