fix(review): tighten qB login check, propagate delete failures end-to-end, close cache race

Post-review fixes for the batch-3.2.8 branch:

- auth() and the setup wizard again require a positive success marker on
  200 responses ('Ok.' body) so a proxy or non-qB service answering
  200 + HTML is not mistaken for a login; 204 stays the qB >= 5.2 success.
- delete_rule no longer wraps a failed torrent deletion into a 200 reply,
  and the WebUI torrents-delete endpoint reports the failure instead of
  answering 'Torrents deleted' unconditionally.
- The close-on-failed-auth teardown now lives once in
  DownloadClient.__aenter__ (client.logout() before raising) instead of
  being copy-pasted into each concrete client.
- search_all() records a cache generation before querying and skips the
  cache write if an invalidation landed in between, so a stale snapshot
  can no longer overwrite a newer invalidation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014w1Z6Nxy6XTRgkFXqPr9Zh
This commit is contained in:
Estrella Pan
2026-07-02 11:57:35 +02:00
parent fa24ec4e2a
commit fe7298689a
12 changed files with 107 additions and 31 deletions

View File

@@ -162,10 +162,11 @@ async def test_downloader(req: TestDownloaderRequest):
data={"username": req.username, "password": req.password},
)
# qBittorrent < 5.2 answers 200 + "Ok."; >= 5.2 answers 204 with
# an empty body on success (#1044).
if (
login_resp.status_code in (200, 204)
and "fails" not in login_resp.text.lower()
# an empty body on success (#1044). Keep the positive body check
# for 200 so a proxy answering 200 + HTML is not reported as a
# working login.
if login_resp.status_code == 204 or (
login_resp.status_code == 200 and "ok" in login_resp.text.lower()
):
return TestResultResponse(
success=True,