[codex] harden today top news AI response parsing - #8
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a new helper function parse_hot_topics_response in app.py to parse and validate the AI response for hot topics, and integrates it into getTodayTopNews. It also adds a unit test suite in tests/test_today_top_news.py to verify the error handling when the AI response is empty. The reviewer suggests improving the robustness of parse_hot_topics_response by gracefully handling JSON decoding errors and validating the presence of the hot_label key in each topic to prevent downstream KeyError exceptions.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| def parse_hot_topics_response(text): | ||
| if not text or not text.strip(): | ||
| raise ValueError("AI response is empty") | ||
|
|
||
| parsed = json.loads(repair_json(text)) | ||
| if not isinstance(parsed, dict): | ||
| raise ValueError("AI response is invalid: expected object with hot_topics") | ||
|
|
||
| topics = parsed.get("hot_topics") | ||
| if not isinstance(topics, list): | ||
| raise ValueError("AI response is invalid: hot_topics must be a list") | ||
|
|
||
| for index, topic in enumerate(topics): | ||
| if not isinstance(topic, dict): | ||
| raise ValueError(f"AI response is invalid: hot_topics[{index}] must be an object") | ||
|
|
||
| return topics |
There was a problem hiding this comment.
To further harden the AI response parsing and prevent unhandled exceptions:
- Handle JSON decoding errors gracefully: If
repair_json(text)produces invalid JSON,json.loadswill raise ajson.JSONDecodeError. Wrapping this in atry-exceptblock and raising a clearValueErrorkeeps the error messages consistent and informative. - Prevent potential
KeyError: IngetTodayTopNews(),needKnow['hot_label']is accessed directly (line 408). If the AI response contains a topic object that is missing thehot_labelkey, this will raise aKeyError. Validating thathot_labelis present in each topic dictionary prevents this cascading failure.
def parse_hot_topics_response(text):
if not text or not text.strip():
raise ValueError("AI response is empty")
try:
parsed = json.loads(repair_json(text))
except json.JSONDecodeError as e:
raise ValueError(f"AI response is not valid JSON: {e}")
if not isinstance(parsed, dict):
raise ValueError("AI response is invalid: expected object with hot_topics")
topics = parsed.get("hot_topics")
if not isinstance(topics, list):
raise ValueError("AI response is invalid: hot_topics must be a list")
for index, topic in enumerate(topics):
if not isinstance(topic, dict):
raise ValueError(f"AI response is invalid: hot_topics[{index}] must be an object")
if "hot_label" not in topic:
raise ValueError(f"AI response is invalid: hot_topics[{index}] is missing 'hot_label'")
return topics
Summary
/todayTopNewsagainst empty or malformed AI selection payloads by validating the top-levelhot_topicsresponse before detail parsingAI response is emptyinstead of cascading into attribute errors when the model returns bad outputWhy
The endpoint previously assumed the model always returned a JSON object with a
hot_topicslist. When the model returned an empty string, the code fell through to.get("hot_topics", [])on a non-dict value and produced an unhelpful failure path.Validation
python3 -m py_compile app.py tests/test_today_top_news.py. .venv/bin/activate && python -m unittest tests/test_today_top_news.py