mirror of
https://github.com/EstrellaXD/Auto_Bangumi.git
synced 2026-04-13 11:09:49 +08:00
fix(error-handling): replace bare except clauses with specific exceptions
- qb_downloader.py: catch httpx network errors in logout() and rename_file() - user.py: log exception details when querying users table fails - download_client.py: log exception when category creation fails - title_parser.py: catch specific exceptions (ValueError, AttributeError, TypeError) instead of broad Exception in raw_parser() Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -73,10 +73,15 @@ class UserDatabase:
|
||||
try:
|
||||
result = self.session.exec(statement)
|
||||
users = list(result.all())
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
# Table may not exist yet during initial setup
|
||||
logger.debug(
|
||||
f"[Database] Could not query users table (may not exist yet): {e}"
|
||||
)
|
||||
users = []
|
||||
if len(users) != 0:
|
||||
return
|
||||
user = User(username="admin", password=get_password_hash("adminadmin"))
|
||||
self.session.add(user)
|
||||
self.session.commit()
|
||||
logger.info("[Database] Created default admin user")
|
||||
|
||||
@@ -26,9 +26,7 @@ class QbDownloader:
|
||||
async def auth(self, retry=3):
|
||||
times = 0
|
||||
timeout = httpx.Timeout(connect=3.1, read=10.0, write=10.0, pool=10.0)
|
||||
self._client = httpx.AsyncClient(
|
||||
timeout=timeout, verify=self.ssl
|
||||
)
|
||||
self._client = httpx.AsyncClient(timeout=timeout, verify=self.ssl)
|
||||
while times < retry:
|
||||
try:
|
||||
resp = await self._client.post(
|
||||
@@ -61,8 +59,12 @@ class QbDownloader:
|
||||
if self._client:
|
||||
try:
|
||||
await self._client.post(self._url("auth/logout"))
|
||||
except Exception:
|
||||
pass
|
||||
except (
|
||||
httpx.ConnectError,
|
||||
httpx.RequestError,
|
||||
httpx.TimeoutException,
|
||||
) as e:
|
||||
logger.debug(f"[Downloader] Logout request failed (non-critical): {e}")
|
||||
await self._client.aclose()
|
||||
self._client = None
|
||||
|
||||
@@ -114,7 +116,9 @@ class QbDownloader:
|
||||
)
|
||||
return resp.json()
|
||||
|
||||
async def add_torrents(self, torrent_urls, torrent_files, save_path, category, tags=None):
|
||||
async def add_torrents(
|
||||
self, torrent_urls, torrent_files, save_path, category, tags=None
|
||||
):
|
||||
data = {
|
||||
"savepath": save_path,
|
||||
"category": category,
|
||||
@@ -133,9 +137,17 @@ class QbDownloader:
|
||||
if torrent_files:
|
||||
if isinstance(torrent_files, list):
|
||||
for i, f in enumerate(torrent_files):
|
||||
files[f"torrents_{i}"] = (f"torrent_{i}.torrent", f, "application/x-bittorrent")
|
||||
files[f"torrents_{i}"] = (
|
||||
f"torrent_{i}.torrent",
|
||||
f,
|
||||
"application/x-bittorrent",
|
||||
)
|
||||
else:
|
||||
files["torrents"] = ("torrent.torrent", torrent_files, "application/x-bittorrent")
|
||||
files["torrents"] = (
|
||||
"torrent.torrent",
|
||||
torrent_files,
|
||||
"application/x-bittorrent",
|
||||
)
|
||||
|
||||
max_retries = 3
|
||||
for attempt in range(max_retries):
|
||||
@@ -153,14 +165,14 @@ class QbDownloader:
|
||||
)
|
||||
await asyncio.sleep(2)
|
||||
else:
|
||||
logger.error(f"[Downloader] Failed to add torrent after {max_retries} attempts: {e}")
|
||||
logger.error(
|
||||
f"[Downloader] Failed to add torrent after {max_retries} attempts: {e}"
|
||||
)
|
||||
raise
|
||||
|
||||
async def get_torrents_by_tag(self, tag: str) -> list[dict]:
|
||||
"""Get all torrents with a specific tag."""
|
||||
resp = await self._client.get(
|
||||
self._url("torrents/info"), params={"tag": tag}
|
||||
)
|
||||
resp = await self._client.get(self._url("torrents/info"), params={"tag": tag})
|
||||
return resp.json()
|
||||
|
||||
async def torrents_delete(self, hash, delete_files: bool = True):
|
||||
@@ -191,7 +203,8 @@ class QbDownloader:
|
||||
logger.debug(f"Conflict409Error: {old_path} >> {new_path}")
|
||||
return False
|
||||
return resp.status_code == 200
|
||||
except Exception:
|
||||
except (httpx.ConnectError, httpx.RequestError, httpx.TimeoutException) as e:
|
||||
logger.warning(f"[Downloader] Failed to rename file {old_path}: {e}")
|
||||
return False
|
||||
|
||||
async def rss_add_feed(self, url, item_path):
|
||||
@@ -216,6 +229,7 @@ class QbDownloader:
|
||||
|
||||
async def rss_set_rule(self, rule_name, rule_def):
|
||||
import json
|
||||
|
||||
await self._client.post(
|
||||
self._url("rss/setRule"),
|
||||
data={"ruleName": rule_name, "ruleDef": json.dumps(rule_def)},
|
||||
|
||||
@@ -70,10 +70,13 @@ class DownloadClient(TorrentPath):
|
||||
"rss_refresh_interval": 30,
|
||||
}
|
||||
await self.client.prefs_init(prefs=prefs)
|
||||
# Category creation may fail if it already exists (HTTP 409) or network issues
|
||||
try:
|
||||
await self.client.add_category("BangumiCollection")
|
||||
except Exception:
|
||||
logger.debug("[Downloader] Cannot add new category, maybe already exists.")
|
||||
except Exception as e:
|
||||
logger.debug(
|
||||
f"[Downloader] Could not add category (may already exist): {e}"
|
||||
)
|
||||
if settings.downloader.path == "":
|
||||
prefs = await self.client.get_app_prefs()
|
||||
settings.downloader.path = self._join_path(prefs["save_path"], "Bangumi")
|
||||
@@ -107,7 +110,9 @@ class DownloadClient(TorrentPath):
|
||||
await asyncio.gather(*[self.set_rule(info) for info in bangumi_info])
|
||||
logger.debug("[Downloader] Finished.")
|
||||
|
||||
async def get_torrent_info(self, category="Bangumi", status_filter="completed", tag=None):
|
||||
async def get_torrent_info(
|
||||
self, category="Bangumi", status_filter="completed", tag=None
|
||||
):
|
||||
return await self.client.torrents_info(
|
||||
status_filter=status_filter, category=category, tag=tag
|
||||
)
|
||||
@@ -137,7 +142,9 @@ class DownloadClient(TorrentPath):
|
||||
async with RequestContent() as req:
|
||||
if isinstance(torrent, list):
|
||||
if len(torrent) == 0:
|
||||
logger.debug(f"[Downloader] No torrent found: {bangumi.official_title}")
|
||||
logger.debug(
|
||||
f"[Downloader] No torrent found: {bangumi.official_title}"
|
||||
)
|
||||
return False
|
||||
if "magnet" in torrent[0].url:
|
||||
torrent_url = [t.url for t in torrent]
|
||||
@@ -149,7 +156,9 @@ class DownloadClient(TorrentPath):
|
||||
# Filter out None values (failed fetches)
|
||||
torrent_file = [f for f in torrent_file if f is not None]
|
||||
if not torrent_file:
|
||||
logger.warning(f"[Downloader] Failed to fetch torrent files for: {bangumi.official_title}")
|
||||
logger.warning(
|
||||
f"[Downloader] Failed to fetch torrent files for: {bangumi.official_title}"
|
||||
)
|
||||
return False
|
||||
torrent_url = None
|
||||
else:
|
||||
@@ -159,7 +168,9 @@ class DownloadClient(TorrentPath):
|
||||
else:
|
||||
torrent_file = await req.get_content(torrent.url)
|
||||
if torrent_file is None:
|
||||
logger.warning(f"[Downloader] Failed to fetch torrent file for: {bangumi.official_title}")
|
||||
logger.warning(
|
||||
f"[Downloader] Failed to fetch torrent file for: {bangumi.official_title}"
|
||||
)
|
||||
return False
|
||||
torrent_url = None
|
||||
# Create tag with bangumi_id for offset lookup during rename
|
||||
@@ -175,10 +186,14 @@ class DownloadClient(TorrentPath):
|
||||
logger.debug(f"[Downloader] Add torrent: {bangumi.official_title}")
|
||||
return True
|
||||
else:
|
||||
logger.debug(f"[Downloader] Torrent added before: {bangumi.official_title}")
|
||||
logger.debug(
|
||||
f"[Downloader] Torrent added before: {bangumi.official_title}"
|
||||
)
|
||||
return False
|
||||
except Exception as e:
|
||||
logger.error(f"[Downloader] Failed to add torrent for {bangumi.official_title}: {e}")
|
||||
logger.error(
|
||||
f"[Downloader] Failed to add torrent for {bangumi.official_title}: {e}"
|
||||
)
|
||||
return False
|
||||
|
||||
async def move_torrent(self, hashes, location):
|
||||
|
||||
@@ -44,7 +44,9 @@ class TitleParser:
|
||||
|
||||
@staticmethod
|
||||
async def tmdb_poster_parser(bangumi: Bangumi):
|
||||
tmdb_info = await tmdb_parser(bangumi.official_title, settings.rss_parser.language)
|
||||
tmdb_info = await tmdb_parser(
|
||||
bangumi.official_title, settings.rss_parser.language
|
||||
)
|
||||
if tmdb_info:
|
||||
logger.debug(f"TMDB Matched, official title is {tmdb_info.title}")
|
||||
bangumi.poster_link = tmdb_info.poster_link
|
||||
@@ -98,9 +100,8 @@ class TitleParser:
|
||||
offset=0,
|
||||
filter=",".join(settings.rss_parser.filter),
|
||||
)
|
||||
except Exception as e:
|
||||
logger.debug(e)
|
||||
logger.warning(f"Cannot parse {raw}.")
|
||||
except (ValueError, AttributeError, TypeError) as e:
|
||||
logger.warning(f"Cannot parse '{raw}': {type(e).__name__}: {e}")
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
|
||||
Reference in New Issue
Block a user