From 8e7e8933e44c6a34be4df6e80072e1cd619338c8 Mon Sep 17 00:00:00 2001 From: Estrella Pan Date: Sun, 25 Jan 2026 11:47:26 +0100 Subject: [PATCH] fix(downloader): add retry logic for transient network errors in add_torrents Handles httpx.ReadError and other network exceptions when adding torrents to qBittorrent by retrying up to 3 times with a 2-second delay. Co-Authored-By: Claude Opus 4.5 --- .../module/downloader/client/qb_downloader.py | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/backend/src/module/downloader/client/qb_downloader.py b/backend/src/module/downloader/client/qb_downloader.py index cbeff7b0..45eb5c49 100644 --- a/backend/src/module/downloader/client/qb_downloader.py +++ b/backend/src/module/downloader/client/qb_downloader.py @@ -135,12 +135,24 @@ class QbDownloader: else: files["torrents"] = ("torrent.torrent", torrent_files, "application/x-bittorrent") - resp = await self._client.post( - self._url("torrents/add"), - data=data, - files=files if files else None, - ) - return resp.text == "Ok." + max_retries = 3 + for attempt in range(max_retries): + try: + resp = await self._client.post( + self._url("torrents/add"), + data=data, + files=files if files else None, + ) + return resp.text == "Ok." + except (httpx.ReadError, httpx.ConnectError, httpx.RequestError) as e: + if attempt < max_retries - 1: + logger.warning( + f"[Downloader] Network error adding torrent (attempt {attempt + 1}/{max_retries}): {e}" + ) + await asyncio.sleep(2) + else: + logger.error(f"[Downloader] Failed to add torrent after {max_retries} attempts: {e}") + raise async def torrents_delete(self, hash, delete_files: bool = True): await self._client.post(