Harden state persistence and fix provider abort handling

- Add safeJsonReplacer to all JSON.stringify calls in storage.ts to prevent
  NaN/Infinity values from corrupting state files and causing queue loss
- Fix LinkSnappy and 1Fichier retry loops: use sleepWithSignal() instead of
  sleep() so abort signals are respected during retry delays
- Fix Debrid-Link polling: replace raw setTimeout with sleepWithSignal() so
  URL generation polling can be cancelled
- Fix Mega-Debrid doConnectApi: clear token cache on 401/403 responses
  instead of caching invalid credentials for 20 minutes
- Add logging when normalizeLoadedSession removes orphaned items so data
  loss during startup is visible in logs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sucukdeluxe
2026-03-26 19:47:58 +01:00
co-authored by Claude Opus 4.6
parent b41b7c9de6
commit e8c6761bf0
2 changed files with 31 additions and 12 deletions
+9 -3
View File
@@ -1545,10 +1545,16 @@ class MegaDebridClient {
});
const text = await response.text();
if (!response.ok) {
if (response.status === 401 || response.status === 403) {
this.clearTokenCache();
}
return null;
}
const payload = parseJsonSafe(text);
if (!payload || payload.response_code !== "ok") {
if (payload && String(payload.response_code || "").toLowerCase().includes("token")) {
this.clearTokenCache();
}
return null;
}
const token = String(payload.token || "").trim();
@@ -2467,7 +2473,7 @@ class DebridLinkClient {
throw new Error("aborted");
}
if (poll > 0) {
await new Promise((resolve) => setTimeout(resolve, 2000));
await sleepWithSignal(2000, signal);
}
const refreshed = await this.fetchDownloaderEntry(apiKey, id, signal);
if (refreshed) {
@@ -2738,7 +2744,7 @@ class LinkSnappyClient {
throw error;
}
if (attempt < REQUEST_RETRIES) {
await sleep(retryDelay(attempt), signal);
await sleepWithSignal(retryDelay(attempt), signal);
}
}
}
@@ -2808,7 +2814,7 @@ class OneFichierClient {
throw error;
}
if (attempt < REQUEST_RETRIES) {
await sleep(retryDelay(attempt), signal);
await sleepWithSignal(retryDelay(attempt), signal);
}
}
}