add retry policy

This commit is contained in:
Fran Jurmanović
2025-06-30 23:04:51 +02:00
parent def1757371
commit 01866b302e
6 changed files with 201 additions and 7 deletions

View File

@@ -6,6 +6,23 @@ import { Client, MessageEmbed, TextChannel } from "discord.js";
dayjs.extend(customParseFormat);
/**
* Retry mechanism for failed date checks
*
* This implementation allows the bot to retry fetching and posting content
* when a date check fails. It will retry at hourly intervals for a number of attempts
* specified by the RETRY_ATTEMPTS environment variable (defaults to 3).
*
* This is useful when:
* 1. The website hasn't updated with today's post yet
* 2. There are temporary network issues
* 3. The website structure changed temporarily
*/
// Sleep function to delay between retry attempts
const sleep = (ms: number): Promise<void> =>
new Promise((resolve) => setTimeout(resolve, ms));
export async function sendDiscordMessage(
client: Client,
url: string,
@@ -57,8 +74,59 @@ export async function sendDiscordMessage(
await Promise.all(promises);
}
/**
* Fetches and sends the next legica-dana post to all Discord channels
*
* This function implements a retry mechanism that will:
* 1. Try to fetch and post the latest content
* 2. If it fails (especially due to date check), wait for 1 hour
* 3. Retry up to the number of times specified in RETRY_ATTEMPTS env var
*
* @param client The Discord client used to send messages
* @throws Error if all retry attempts fail
*/
export async function sendNextMessage(client: Client): Promise<void> {
const href = await getFirstHtml();
if (!href) throw new Error("URL cannot be empty!");
await sendDiscordMessage(client, href, dayjs());
// Get max retry attempts from config
const maxRetries = config.RETRY_ATTEMPTS;
let attempts = 0;
let lastError: Error | null = null;
// Keep trying until we've reached max attempts
while (attempts < maxRetries) {
try {
// Get the URL of the latest post
const href = await getFirstHtml();
if (!href) throw new Error("URL cannot be empty!");
// Try to send the message
await sendDiscordMessage(client, href, dayjs());
// If successful, return
return;
} catch (error: unknown) {
attempts++;
const typedError = error instanceof Error ? error : new Error(String(error));
lastError = typedError;
// Log the retry attempt
console.error(
`Attempt ${attempts}/${maxRetries} failed: ${typedError.message}`
);
// If we've reached max attempts, throw the last error
if (attempts >= maxRetries) {
throw new Error(
`Failed after ${attempts} attempts. Last error: ${
lastError?.message || "Unknown error"
}`
);
}
// Wait for 1 hour before retrying (3600000 ms)
console.log(
`Waiting 1 hour before retry attempt ${attempts + 1}/${maxRetries}...`
);
await sleep(3600000);
}
}
}