From 60c0a504c30efbc3bb40906403a5fd05dd74662b Mon Sep 17 00:00:00 2001 From: Jason Hall Date: Mon, 18 Mar 2024 16:36:41 -0400 Subject: [PATCH] add backoff and retry to fetches (#17) Signed-off-by: Jason Hall --- index.js | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 15e76d7..f98527e 100644 --- a/index.js +++ b/index.js @@ -14,12 +14,32 @@ if (!scope || !identity) { process.exit(1); } +async function fetchWithRetry(url, options = {}, retries = 3, initialDelay = 1000) { + let attempt = 1; + while (retries > 0) { + try { + const response = await fetch(url, options); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + return response; + } catch (error) { + console.warn(`Attempt ${attempt} failed. Error: ${error.message}`); + const delay = Math.min(2 ** attempt * initialDelay, 10000); // Limit max delay to 10 seconds + await new Promise(resolve => setTimeout(resolve, delay)); + attempt++; + retries--; + } + } + throw new Error(`Fetch failed after ${attempt} attempts.`); +} + (async function main() { // You can use await inside this function block try { - const res = await fetch(`${actionsUrl}&audience=octo-sts.dev`, { headers: { 'Authorization': `Bearer ${actionsToken}` } }); + const res = await fetchWithRetry(`${actionsUrl}&audience=octo-sts.dev`, { headers: { 'Authorization': `Bearer ${actionsToken}` } }, 5); const json = await res.json(); - const res2 = await fetch(`https://octo-sts.dev/sts/exchange?scope=${scope}&identity=${identity}`, { headers: { 'Authorization': `Bearer ${json.value}` } }); + const res2 = await fetchWithRetry(`https://octo-sts.dev/sts/exchange?scope=${scope}&identity=${identity}`, { headers: { 'Authorization': `Bearer ${json.value}` } }); const json2 = await res2.json(); if (!json2.token) { console.log(`::error::${json2.message}`); process.exit(1); }