From 3d82d00e54d9028722f6922465116254649f274d Mon Sep 17 00:00:00 2001 From: Sucukdeluxe Date: Wed, 17 Jun 2026 20:38:32 +0200 Subject: [PATCH] Fix: Mega-Debrid 'Linkgenerierung lieferte kein Ergebnis' nicht mehr als 30s-Cooldown (schneller Transient) Eine leere Mega-Debrid-API-Antwort (success, aber kein Download-Link -> debrid.ts:1927 'Linkgenerierung lieferte kein Ergebnis') fiel in classifyAccountFailure in den Default-Zweig -> 30s Account-Cooldown ('Mega-Debrid Cooldown, neuer Versuch in 31s'). Das ist KEIN Limit-/Quota-Signal, sondern ein transienter API-Blip, der praktisch sofort wieder funktioniert (vom Nutzer live beobachtet: danach ging es). Fix: eigener Zweig klassifiziert die leere Antwort wie die anderen transienten Resolve-Fehler (cooldownMs 0, kein Account-Cooldown) -> der Download-Manager nimmt den schnellen Transient-Retry-Pfad (3s, eskaliert auf max 10s) statt 31s zu warten. Kein limitSignal (kein until-restart-Park). Rot-bewiesener Test (ohne Fix cooldownMs 30000; mit Fix 0 + Meldung trifft isMegaDebridTransientResolveFailure). Volle Suite 894 gruen, tsc=6. --- src/main/debrid.ts | 4 ++++ tests/debrid.test.ts | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/src/main/debrid.ts b/src/main/debrid.ts index 23315f2..6db35fa 100644 --- a/src/main/debrid.ts +++ b/src/main/debrid.ts @@ -2207,6 +2207,10 @@ class MegaDebridClient { return { fatal: false, cooldownMs: 0, message: germanMegaDebridResolveReason(errorText), category: "temporary" }; } + if (/lieferte kein ergebnis|linkgenerierung[^.]*kein ergebnis/i.test(errorText)) { + return { fatal: false, cooldownMs: 0, message: germanMegaDebridResolveReason(errorText), category: "temporary" }; + } + if (/permanent ungültig|hosternotavailable|file.?not.?found|file.?unavailable|link.?is.?dead/i.test(errorText)) { return { fatal: true, cooldownMs: 0, message: errorText, category: "skip" }; } diff --git a/tests/debrid.test.ts b/tests/debrid.test.ts index 353583c..cc38582 100644 --- a/tests/debrid.test.ts +++ b/tests/debrid.test.ts @@ -3,6 +3,7 @@ import { defaultSettings, REQUEST_RETRIES } from "../src/main/constants"; import { parseDebridLinkApiKeys } from "../src/shared/debrid-link-keys"; import { getMegaDebridAccountId } from "../src/shared/mega-debrid-accounts"; import { getProviderUsageDayKey } from "../src/shared/provider-daily-limits"; +import { isMegaDebridTransientResolveFailure } from "../src/shared/mega-debrid-errors"; import { classifyMegaDebridAccountFailureForTests, clearMegaDebridEmptyResponseStreak, DebridService, extractRapidgatorFilenameFromHtml, fetchAllDebridHostInfo, fetchDebridLinkHostLimits, filenameFromRapidgatorUrlPath, getDebridLinkKeyCooldownStateForTests, getDebridLinkKeyRuntimeStateForTests, getMegaDebridAccountCooldownState, leadProviderChainWith, MEGA_DEBRID_EMPTY_STREAK_UNTIL_RESTART, MEGA_DEBRID_STICKY_LINKS, normalizeResolvedFilename, primeMegaDebridUntilRestartForTests, recordMegaDebridEmptyResponseStreak, resetDebridLinkRuntimeStateForTests, resetMegaDebridRuntimeStateForTests } from "../src/main/debrid"; const originalFetch = globalThis.fetch; @@ -2100,6 +2101,14 @@ describe("debrid service", () => { expect(genuineEmpty.limitSignal).toBe(true); }); + it("classifies an empty Mega-Debrid API result ('Linkgenerierung lieferte kein Ergebnis') as a fast transient, not a 30s cooldown", () => { + const result = classifyMegaDebridAccountFailureForTests(new Error("Mega-Debrid API: Linkgenerierung lieferte kein Ergebnis")); + expect(result.fatal).toBe(false); + expect(result.cooldownMs).toBe(0); + expect(result.limitSignal).toBeFalsy(); + expect(isMegaDebridTransientResolveFailure(result.message)).toBe(true); + }); + it("skips a Mega-Debrid account parked until restart and rotates to the next, without re-testing it", async () => { const settings = { ...defaultSettings(),