Fix: Mega-Cooldown vor Tagesreset-Park bevorzugen + Token-Truncation + Rewind-Fail-Haertung (Synthese-Pass)
Capstone-Synthese/Regressions-Pass ueber den kumulativen Audit-Diff (v1.7.212..HEAD) hat 3 Fix-INTERAKTIONEN gefunden — der Rest komponiert sauber. C1 (MED): Sind BEIDE Mega-Modi aktiv (API + Web), aggregiert die Provider-Kette bei Fehlschlag beide Token in einen String: `mega_debrid_reset_park:LONG` (API bis Tagesreset geparkt) + `mega_debrid_cooldown:30000` (Web nur kurz im Cooldown). Der Manager pruefte reset_park VOR cooldown → das Item wurde ~24h geparkt, obwohl der Web-Modus in ~30s wieder verfuegbar gewesen waere. Fix: den Cooldown-Zweig (kuerzerer Delay) VOR dem reset_park-Zweig pruefen; der erholbarere Pfad gewinnt. C2 (LOW): Das reset_park-Token konnte von compactErrorText (220-Zeichen-Cap) abgeschnitten werden, wenn Mega nicht der Lead-Provider war und ein vorheriger Provider eine lange Fehlermeldung lieferte → Park wurde still uebersprungen und Mega am Tageslimit weiter gehaemmert. Fix: beide Mega-Token aus der UNGEKUERZTEN error.message parsen statt aus dem gekuerzten Anzeige-String. RANGE1-truncate-fail (LOW, Haertung + Doku-Korrektur): Der v1.7.219-Commit behauptete, das Setzen von downloadedBytes ZUERST rette den Fall eines fehlgeschlagenen finalen Rewind-truncate ueber den Re-Entry-prealloc-reconcile. Das stimmt nicht — bei truncate-Fehler finalisiert tryFinalizeItemFromDisk die exakt-langen Garbage-Datei VOR dem Re-Entry (net-neutral vs pre-audit, KEINE Regression, aber der Claim war falsch). Haertung: bei fehlgeschlagenem finalem Rewind die Teil-Datei verwerfen (rmSync + downloadedBytes=0) → Finalize lehnt ab → sauberer Re-Download. Best-effort (faellt der rm auch, bleibt es net-neutral) — macht den 219-Claim jetzt wahr. Rot-bewiesen: Single-Pass-processItem-Test mit Aggregat beider Mega-Token → retryAfter < 60s (Cooldown) und fullStatus "Cooldown" statt "Tagesreset"; mit deaktiviertem Cooldown-Zweig (alte Reihenfolge) ~24h-Park = rot. Volle Suite 886 gruen, tsc=6.
This commit is contained in:
@@ -9436,24 +9436,8 @@ export class DownloadManager extends EventEmitter {
|
||||
return;
|
||||
}
|
||||
|
||||
const megaResetPark = parseMegaDebridResetPark(errorText);
|
||||
if (megaResetPark && active.unrestrictRetries < maxUnrestrictRetries) {
|
||||
active.unrestrictRetries += 1;
|
||||
item.retries += 1;
|
||||
logger.warn(`Mega-Debrid bis Tagesreset gesperrt: item=${item.fileName || item.id}, retry=${active.unrestrictRetries}/${retryDisplayLimit}, delay=${megaResetPark.delayMs}ms, link=${item.url.slice(0, 80)}`);
|
||||
this.queueRetry(
|
||||
item,
|
||||
active,
|
||||
megaResetPark.delayMs,
|
||||
`Mega-Debrid bis Tagesreset gesperrt, Pause ${Math.ceil(megaResetPark.delayMs / 1000)}s`
|
||||
);
|
||||
item.lastError = megaResetPark.detail || errorText;
|
||||
this.persistSoon();
|
||||
this.emitState();
|
||||
return;
|
||||
}
|
||||
|
||||
const megaCooldownRetry = parseMegaDebridCooldownRetry(errorText);
|
||||
const megaRawError = error instanceof Error ? String(error.message || "") : String(error || "");
|
||||
const megaCooldownRetry = parseMegaDebridCooldownRetry(megaRawError);
|
||||
if (megaCooldownRetry && active.unrestrictRetries < maxUnrestrictRetries) {
|
||||
active.unrestrictRetries += 1;
|
||||
item.retries += 1;
|
||||
@@ -9470,6 +9454,23 @@ export class DownloadManager extends EventEmitter {
|
||||
return;
|
||||
}
|
||||
|
||||
const megaResetPark = parseMegaDebridResetPark(megaRawError);
|
||||
if (megaResetPark && active.unrestrictRetries < maxUnrestrictRetries) {
|
||||
active.unrestrictRetries += 1;
|
||||
item.retries += 1;
|
||||
logger.warn(`Mega-Debrid bis Tagesreset gesperrt: item=${item.fileName || item.id}, retry=${active.unrestrictRetries}/${retryDisplayLimit}, delay=${megaResetPark.delayMs}ms, link=${item.url.slice(0, 80)}`);
|
||||
this.queueRetry(
|
||||
item,
|
||||
active,
|
||||
megaResetPark.delayMs,
|
||||
`Mega-Debrid bis Tagesreset gesperrt, Pause ${Math.ceil(megaResetPark.delayMs / 1000)}s`
|
||||
);
|
||||
item.lastError = megaResetPark.detail || errorText;
|
||||
this.persistSoon();
|
||||
this.emitState();
|
||||
return;
|
||||
}
|
||||
|
||||
if (isMegaDebridTransientResolveFailure(errorText) && active.unrestrictRetries < maxUnrestrictRetries) {
|
||||
active.unrestrictRetries += 1;
|
||||
item.retries += 1;
|
||||
@@ -10607,7 +10608,12 @@ export class DownloadManager extends EventEmitter {
|
||||
rewindTarget
|
||||
});
|
||||
} catch (rewindError) {
|
||||
logAttemptEvent("WARN", "Resume-Schutz: finales Rueckspulen fehlgeschlagen", {
|
||||
try {
|
||||
fs.rmSync(effectiveTargetPath, { force: true });
|
||||
item.downloadedBytes = 0;
|
||||
} catch {
|
||||
}
|
||||
logAttemptEvent("WARN", "Resume-Schutz: finales Rueckspulen fehlgeschlagen, Teil-Datei verworfen", {
|
||||
attempt,
|
||||
written,
|
||||
rewindTarget,
|
||||
|
||||
Reference in New Issue
Block a user