add retry policy
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user