From 144b7c05c97efd7deddfadb2ad88d41dcc79324d Mon Sep 17 00:00:00 2001 From: Claude Dev Date: Sun, 29 Mar 2026 14:53:42 +0200 Subject: [PATCH] fix: Pipeline JSON-Parsing + defensive Zugriffe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Curator/Writer: Doppelt-encodiertes JSON abfangen (isinstance + json.loads) - Pipeline: .get() statt direkte Dict-Zugriffe gegen TypeError - TypeError zum except-Block hinzugefügt Co-Authored-By: Claude Opus 4.6 (1M context) --- src/agents/blog/blog_curator.py | 10 ++++++++-- src/agents/blog/blog_pipeline.py | 8 +++++--- src/agents/blog/blog_writer.py | 10 ++++++++-- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/agents/blog/blog_curator.py b/src/agents/blog/blog_curator.py index baff7ee..abefeae 100644 --- a/src/agents/blog/blog_curator.py +++ b/src/agents/blog/blog_curator.py @@ -139,8 +139,14 @@ Antworte als JSON-Array: try: topics = _extract_json(result) + # Doppelt-encodiertes JSON abfangen + if isinstance(topics, str): + topics = json.loads(topics) + if not isinstance(topics, list): + logger.error(f"Curator: Unerwarteter Typ {type(topics).__name__}, erwartet list") + return [] logger.info(f"Curator: {len(topics)} Themen ausgewählt (${usage.cost_usd:.4f})") return topics - except (json.JSONDecodeError, IndexError) as e: - logger.error(f"Curator JSON-Parse-Fehler: {e}\nRaw: {result[:500]}") + except (json.JSONDecodeError, IndexError, TypeError) as e: + logger.error(f"Curator JSON-Parse-Fehler: {e}\nRaw: {result[:300]}") return [] diff --git a/src/agents/blog/blog_pipeline.py b/src/agents/blog/blog_pipeline.py index 75375fb..5ca7522 100644 --- a/src/agents/blog/blog_pipeline.py +++ b/src/agents/blog/blog_pipeline.py @@ -73,18 +73,20 @@ async def run_pipeline(): logger.warning("Keine Themen ausgewählt -- Pipeline beendet") return - logger.info(f"{len(topics)} Themen ausgewählt: {[t['topic'] for t in topics]}") + logger.info(f"{len(topics)} Themen ausgewählt: {[t.get('topic', '?') if isinstance(t, dict) else str(t)[:50] for t in topics]}") # 2. Artikel schreiben logger.info("Schritt 2: Artikel schreiben...") articles = [] for topic in topics: - logger.info(f"Schreibe: {topic['topic']} ({topic['category']})") + topic_title = topic.get('topic', 'Unbekannt') if isinstance(topic, dict) else str(topic)[:50] + topic_cat = topic.get('category', '?') if isinstance(topic, dict) else '?' + logger.info(f"Schreibe: {topic_title} ({topic_cat})") article = await write_article(topic, call_claude) if article: articles.append(article) else: - logger.warning(f"Artikel fehlgeschlagen: {topic['topic']}") + logger.warning(f"Artikel fehlgeschlagen: {topic_title}") if not articles: logger.warning("Keine Artikel geschrieben -- Pipeline beendet") diff --git a/src/agents/blog/blog_writer.py b/src/agents/blog/blog_writer.py index 3f938ab..173ab8c 100644 --- a/src/agents/blog/blog_writer.py +++ b/src/agents/blog/blog_writer.py @@ -149,10 +149,16 @@ Falls das Thema einen geographischen Bezug hat, fülle geo_data: try: article = _extract_json(result) + # Doppelt-encodiertes JSON abfangen + if isinstance(article, str): + article = json.loads(article) + if not isinstance(article, dict): + logger.error(f"Writer: Unerwarteter Typ {type(article).__name__}") + return None article["category"] = topic["category"] article["monitor_event_ids"] = topic.get("incident_ids", []) logger.info(f"Writer: Artikel '{article['title']}' geschrieben (${usage.cost_usd:.4f})") return article - except (json.JSONDecodeError, IndexError, KeyError) as e: - logger.error(f"Writer JSON-Parse-Fehler: {e}\nRaw: {result[:500]}") + except (json.JSONDecodeError, IndexError, KeyError, TypeError) as e: + logger.error(f"Writer JSON-Parse-Fehler: {e}\nRaw: {result[:300]}") return None