From d980c3c71420cbb49ed1823b7f713f6321e448fe Mon Sep 17 00:00:00 2001 From: Estrella Pan Date: Sun, 1 Mar 2026 08:12:18 +0100 Subject: [PATCH] fix(parser): handle None return from raw_parser to avoid AttributeError (#992) When raw_parser fails to parse non-episodic resources (movies, collections), it returns None. Add guard clause in title_parser to skip these gracefully instead of crashing on attribute access. Downgrade log level from error to info since this is expected behavior. Co-Authored-By: Claude Opus 4.6 --- backend/src/module/parser/analyser/raw_parser.py | 7 ++++--- backend/src/module/parser/title_parser.py | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/backend/src/module/parser/analyser/raw_parser.py b/backend/src/module/parser/analyser/raw_parser.py index bfe0ab6a..df94a528 100644 --- a/backend/src/module/parser/analyser/raw_parser.py +++ b/backend/src/module/parser/analyser/raw_parser.py @@ -14,8 +14,8 @@ SOURCE_RE = re.compile(r"B-Global|[Bb]aha|[Bb]ilibili|AT-X|Web") SUB_RE = re.compile(r"[简繁日字幕]|CH|BIG5|GB") FALLBACK_EP_PATTERNS = [ - re.compile(r" (\d+) ?(?=\[)"), # #876/#910: digits before [ - re.compile(r"\[(\d+)\(\d+\)\]"), # #773: [02(57)] + re.compile(r" (\d+) ?(?=\[)"), # #876/#910: digits before [ + re.compile(r"\[(\d+)\(\d+\)\]"), # #773: [02(57)] ] PREFIX_RE = re.compile(r"[^\w\s\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff-]") @@ -32,6 +32,7 @@ def _fallback_parse(content_title: str) -> tuple | None: return season_info, episode_info, other return None + CHINESE_NUMBER_MAP = { "一": 1, "二": 2, @@ -201,7 +202,7 @@ def process(raw_title: str): def raw_parser(raw: str) -> Episode | None: ret = process(raw) if ret is None: - logger.error(f"Parser cannot analyse {raw}") + logger.info(f"Detected non-episodic resource: {raw}, skipping.") return None name_en, name_zh, name_jp, season, sr, episode, sub, dpi, source, group = ret return Episode( diff --git a/backend/src/module/parser/title_parser.py b/backend/src/module/parser/title_parser.py index ebb91d92..b56b23fb 100644 --- a/backend/src/module/parser/title_parser.py +++ b/backend/src/module/parser/title_parser.py @@ -68,6 +68,8 @@ class TitleParser: episode = Episode(**episode_dict) else: episode = raw_parser(raw) + if episode is None: + return None titles = { "zh": episode.title_zh,