Fix: Mega-Web Selbst-Cooldown bei belegter Queue + Legacy-Config Mega-Demotion (Audit Runde 9+10)
MW-1 (HIGH): Ein gesunder Mega-Web-Account wurde 120s gesperrt, wenn der
60s-Gesamttimeout ablief, waehrend die Umwandlung noch SERIELL in der
per-Account-Single-Flight-Queue auf ihren Vorgaenger wartete - also bevor echte
Arbeit begann. Die Queue-Wartezeit zaehlte zu elapsedMs (>= 8s), sodass der
Abbruch faelschlich wie ein In-Arbeit-Abbruch eines langsamen Accounts gewertet
wurde. Genau die gemeldete 'Tool sperrt sich selbst'-Klasse (Web-Variante).
Zweiteilig: (1) MegaWebFallback.runExclusive trackt workStarted und meldet einen
Abbruch-vor-Arbeitsbeginn als Queue-Timeout statt aborted:mega-web;
(2) unrestrictViaWeb bewahrt diese Klassifikation statt sie zu aborted:debrid zu
plaetten -> die Rotation trifft die Queue-Timeout-Ausnahme (cooldownMs 0) statt
den Abbruch-Cooldown. Ein echter In-Arbeit-Abbruch sperrt weiterhin (langsame
Accounts korrekt ueberspringen). Nach dem No-Cooldown-Pfad rotiert der Retry per
In-Flight-Tiefe auf einen freien Account.
SET-MIG-01 (MED): Eine Config von vor v1.6.90 kannte die getrennten
Mega-API/Web-Enable-Flags nicht. readSettingsFile merged {...defaultSettings(),
...parsed}, also fuellten die false-Defaults die fehlenden Flags BEVOR
normalizeSettings lief -> der creds-basierte Migrationszweig war tot, Mega blieb
auf aus trotz vorhandener Creds und wurde beim ersten Settings-Save still aus der
providerOrder demotet. Fix: reine migrateLegacyMegaEnableFlags seedet die Flags
nur, wenn BEIDE im RAW-parsed fehlen und Creds vorhanden sind (absent-both als
einziger sicherer Trigger; present-false bleibt unberuehrt = bewusst-deaktiviert
nicht re-aktivieren). Greift nur bei Legacy-Configs, die seit dem Upgrade noch
nicht neu gespeichert wurden.
Je rot-bewiesener Test (per Temp-Revert verifiziert, nicht-vakuum). Volle Suite
890 gruen, tsc unveraendert (6 vorbestehende Fehler). Runde-9/10-Doku + die zwei
offenen Nutzer-Entscheidungen aktualisiert.
This commit is contained in:
@@ -1961,6 +1961,43 @@ describe("debrid service", () => {
|
||||
expect(result.directUrl).toBe("https://mega-web.example/ok.rar");
|
||||
}, 20000);
|
||||
|
||||
it("setzt KEINEN Account-Cooldown, wenn der Mega-Web-Abbruch nur ein Queue-Timeout war (Account war belegt, nicht ungesund)", async () => {
|
||||
process.env.RD_MEGA_ABORT_MIN_RUN_MS = "0";
|
||||
const settings = {
|
||||
...defaultSettings(),
|
||||
token: "",
|
||||
bestToken: "",
|
||||
allDebridToken: "",
|
||||
megaLogin: "user",
|
||||
megaPassword: "pass",
|
||||
megaCredentials: "user:pass",
|
||||
megaDebridPreferApi: false,
|
||||
providerOrder: [] as const,
|
||||
providerPrimary: "megadebrid" as const,
|
||||
providerSecondary: "none" as const,
|
||||
providerTertiary: "none" as const,
|
||||
autoProviderFallback: false
|
||||
};
|
||||
globalThis.fetch = (async () => new Response("error", { status: 500 })) as typeof fetch;
|
||||
|
||||
const controller = new AbortController();
|
||||
let calls = 0;
|
||||
const megaWeb = vi.fn(async () => {
|
||||
calls += 1;
|
||||
controller.abort("caller-timeout");
|
||||
throw new Error("Mega-Web Queue-Timeout (abgebrochen nach 60s Wartezeit, Account war belegt)");
|
||||
});
|
||||
|
||||
const service = new DebridService(settings, { megaWebUnrestrict: megaWeb });
|
||||
await expect(
|
||||
service.unrestrictLink("https://rapidgator.net/file/queue-timeout-no-cooldown", controller.signal)
|
||||
).rejects.toThrow();
|
||||
|
||||
const key = `${getMegaDebridAccountId("user")}:web`;
|
||||
expect(getMegaDebridAccountCooldownState(key)).toBeNull();
|
||||
expect(calls).toBeGreaterThanOrEqual(1);
|
||||
}, 20000);
|
||||
|
||||
it("escalates a Mega-Debrid account to 'until restart' after the empty-response streak threshold", () => {
|
||||
const key = `${getMegaDebridAccountId("user1")}:web`;
|
||||
expect(MEGA_DEBRID_EMPTY_STREAK_UNTIL_RESTART).toBe(3);
|
||||
|
||||
Reference in New Issue
Block a user