From 06990c26beacf93e16a1e4a9f8bbfb06e0b68996 Mon Sep 17 00:00:00 2001 From: Jacob Gad Date: Fri, 17 Mar 2023 10:19:00 +1100 Subject: [PATCH] feat: :sparkles: Add retry logic and error handeling service is persistent and does not error out --- src/index.ts | 24 ++++++++++++++++-------- src/utils.test.ts | 4 ++-- src/utils.ts | 24 +++++++++++------------- 3 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/index.ts b/src/index.ts index d6cf46a..2b71b80 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ import type { Record } from './schemas'; import { updatedDNSRecordSchema, createdDNSRecord } from './schemas'; import { recordSchema } from './schemas'; -import { log, vercelAxios } from './utils'; +import { log, retry, vercelAxios } from './utils'; import env from './env'; import { z } from 'zod'; @@ -60,14 +60,22 @@ async function createDNSRecord(name: string, value: string) { } async function main() { - const publicIp = await getPublicIp(); - const records = await getDNSRecords(); + try { + const publicIp = await retry(getPublicIp); + const records = await retry(getDNSRecords); - env.subdomains.forEach(async (subdomain) => { - const record = records?.find((record) => record.name === subdomain); - if (!record) await createDNSRecord(subdomain, publicIp); - if (record && record.value !== publicIp) await updateDNSRecord(record, publicIp); - }); + env.subdomains.forEach(async (subdomain) => { + const record = records?.find((record) => record.name === subdomain); + if (!record) await retry(() => createDNSRecord(subdomain, publicIp)); + if (record && record.value !== publicIp) await retry(() => updateDNSRecord(record, publicIp)); + }); + } catch (error) { + log({ + status: 'ERROR', + function: 'main', + error: 'Failed after 3 attempts, will try again in 30 min', + }); + } } main(); diff --git a/src/utils.test.ts b/src/utils.test.ts index 21fa780..2e0c87d 100644 --- a/src/utils.test.ts +++ b/src/utils.test.ts @@ -1,9 +1,9 @@ /* eslint-disable no-console */ -import { retry } from 'utils'; +import { retry } from './utils'; function getValue() { return new Promise((resolve, reject) => - Math.random() < 0.1 ? resolve('SUCCESS') : reject('ERROR') + Math.random() < 0 ? resolve('SUCCESS') : reject('ERROR') ); } diff --git a/src/utils.ts b/src/utils.ts index 2d7b8f5..fe3e952 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -18,17 +18,15 @@ export function log(props: ConsoleError) { } } -export function retry(func: () => Promise, attempt = 0): Promise { - return new Promise( - (resolve) => - setTimeout(async () => { - try { - const value = await func(); - resolve(value); - } catch (error) { - console.error('ERROR:', func.name, 'attempt', attempt, '->', error); - resolve(retry(func, attempt + 1)); - } - }, 1000 * 10) //10 seconds - ); +export function retry(func: () => Promise, maxAttempt = 3, currentAttempt = 1): Promise { + return new Promise(async (resolve, reject) => { + try { + const value = await func(); + resolve(value); + } catch (error) { + console.error('ERROR:', func.name, 'attempt', currentAttempt, '->', error); + if (currentAttempt >= maxAttempt) return reject(error); + resolve(retry(func, maxAttempt, currentAttempt + 1)); + } + }); }