refactor: Update message deletion logic to handle rate limits and improve error handling
This commit is contained in:
@@ -33,15 +33,22 @@ export async function POST(request: Request) {
|
||||
const [parts]: any[] = await connection.query('SELECT discord_message_id FROM file_parts WHERE file_id = ?', [file_id]);
|
||||
|
||||
if (parts.length > 0) {
|
||||
const deletePromises = parts.map((part: { discord_message_id: string }) => {
|
||||
if (!part.discord_message_id) return Promise.resolve();
|
||||
for (const part of parts) {
|
||||
if (!part.discord_message_id) continue;
|
||||
const deleteUrl = `https://discord.com/api/v10/channels/${process.env.DISCORD_CHANNEL_ID}/messages/${part.discord_message_id}`;
|
||||
return fetch(deleteUrl, {
|
||||
try {
|
||||
const res = await fetch(deleteUrl, {
|
||||
method: 'DELETE',
|
||||
headers: { 'Authorization': `Bot ${process.env.DISCORD_BOT_TOKEN}` },
|
||||
});
|
||||
});
|
||||
await Promise.allSettled(deletePromises);
|
||||
if (!res.ok && res.status !== 404) {
|
||||
console.warn(`Cleanup: Failed to delete message ${part.discord_message_id}. Status: ${res.status}`);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`Cleanup: Error deleting message ${part.discord_message_id}:`, e);
|
||||
}
|
||||
await new Promise(resolve => setTimeout(resolve, 1000)); // 1s delay
|
||||
}
|
||||
}
|
||||
|
||||
await connection.query('DELETE FROM file_parts WHERE file_id = ?', [file_id]);
|
||||
@@ -65,15 +72,22 @@ export async function POST(request: Request) {
|
||||
);
|
||||
|
||||
if (partsRows.length > 0) {
|
||||
const deletePromises = partsRows.map((part: { discord_message_id: string }) => {
|
||||
if (!part.discord_message_id) return Promise.resolve();
|
||||
for (const part of partsRows) {
|
||||
if (!part.discord_message_id) continue;
|
||||
const deleteUrl = `https://discord.com/api/v10/channels/${process.env.DISCORD_CHANNEL_ID}/messages/${part.discord_message_id}`;
|
||||
return fetch(deleteUrl, {
|
||||
try {
|
||||
const res = await fetch(deleteUrl, {
|
||||
method: 'DELETE',
|
||||
headers: { 'Authorization': `Bot ${process.env.DISCORD_BOT_TOKEN}` },
|
||||
});
|
||||
});
|
||||
await Promise.allSettled(deletePromises);
|
||||
if (!res.ok && res.status !== 404) {
|
||||
console.warn(`Cleanup: Failed to delete message ${part.discord_message_id}. Status: ${res.status}`);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`Cleanup: Error deleting message ${part.discord_message_id}:`, e);
|
||||
}
|
||||
await new Promise(resolve => setTimeout(resolve, 1000)); // 1s delay
|
||||
}
|
||||
}
|
||||
|
||||
await connection.query('UPDATE files SET deleted = 1 WHERE id = ?', [file_id]);
|
||||
|
||||
@@ -35,28 +35,33 @@ export async function POST(request: Request) {
|
||||
[file_id]
|
||||
);
|
||||
|
||||
// 3. Delete each message from Discord using the Bot API
|
||||
const deletePromises = partsRows.map((part: { discord_message_id: string }) => {
|
||||
// 3. Delete each message from Discord sequentially to avoid rate limits
|
||||
for (const part of partsRows) {
|
||||
if (!part.discord_message_id) continue;
|
||||
|
||||
const deleteUrl = `https://discord.com/api/v10/channels/${process.env.DISCORD_CHANNEL_ID}/messages/${part.discord_message_id}`;
|
||||
return fetch(deleteUrl, {
|
||||
try {
|
||||
const res = await fetch(deleteUrl, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Authorization': `Bot ${process.env.DISCORD_BOT_TOKEN}`,
|
||||
headers: { 'Authorization': `Bot ${process.env.DISCORD_BOT_TOKEN}` },
|
||||
});
|
||||
|
||||
if (!res.ok && res.status !== 404) { // Don't warn on 404 (already deleted)
|
||||
console.warn(`Failed to delete message ${part.discord_message_id}. Status: ${res.status}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const results = await Promise.allSettled(deletePromises);
|
||||
results.forEach(result => {
|
||||
if (result.status === 'rejected') {
|
||||
console.warn('Failed to delete a message from Discord:', result.reason);
|
||||
} catch (e) {
|
||||
console.error(`Error deleting message ${part.discord_message_id}:`, e);
|
||||
}
|
||||
});
|
||||
|
||||
// 4. Mark the file as deleted in the database (soft delete)
|
||||
await connection.query('UPDATE files SET deleted = 1 WHERE id = ?', [file_id]);
|
||||
// Wait 1 second between delete requests to avoid hitting Discord's rate limits.
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
}
|
||||
|
||||
return NextResponse.json({ success: true, message: 'File marked for deletion.' });
|
||||
// 4. Hard delete the file from the database
|
||||
await connection.query('DELETE FROM file_parts WHERE file_id = ?', [file_id]);
|
||||
await connection.query('DELETE FROM files WHERE id = ?', [file_id]);
|
||||
|
||||
return NextResponse.json({ success: true, message: 'File permanently deleted.' });
|
||||
|
||||
} finally {
|
||||
connection.release();
|
||||
|
||||
@@ -110,7 +110,7 @@ export default function DownloadPage() {
|
||||
const response = await fetchWithRetry(`/api/download-part/${file_id}/${part.part_index}`);
|
||||
const buffer = await response.arrayBuffer();
|
||||
encryptedParts[part.part_index] = { index: part.part_index, data: buffer };
|
||||
setDownloadedBytes(prev => prev + buffer.byteLength);
|
||||
setDownloadedBytes(prev => prev + part.size);
|
||||
setProgress(prev => prev + (1 / metadata.num_parts) * 50);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user