fix: Rate-Limit-Fehler der Claude CLI korrekt erkennen und loggen

Bisher wurde bei Exit Code 1 nur stderr gelesen, wodurch Rate-Limit-Meldungen
auf stdout (als JSON) verloren gingen. Jetzt wird stdout zusätzlich geprüft und
Rate-Limit-Fehler als [rate_limit] geloggt.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dieser Commit ist enthalten in:
Claude Dev
2026-03-12 18:44:59 +01:00
Ursprung 91d412a797
Commit b124208fb9

Datei anzeigen

@@ -54,7 +54,12 @@ async def call_claude(prompt: str, tools: str | None = "WebSearch,WebFetch", mod
if tools:
cmd.extend(["--allowedTools", tools])
else:
cmd.extend(["--max-turns", "1"])
cmd.extend(["--max-turns", "1", "--allowedTools", ""])
cmd.extend(["--append-system-prompt",
"CRITICAL: You are a JSON-only output agent. "
"Output EXCLUSIVELY a single valid JSON object. "
"No explanatory text, no markdown fences, no continuation of previous responses. "
"Start your response with { and end with }."])
process = await asyncio.create_subprocess_exec(
*cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE,
@@ -76,8 +81,21 @@ async def call_claude(prompt: str, tools: str | None = "WebSearch,WebFetch", mod
if process.returncode != 0:
error_msg = stderr.decode("utf-8", errors="replace").strip()
logger.error(f"Claude CLI Fehler (Exit {process.returncode}): {error_msg}")
raise RuntimeError(f"Claude CLI Fehler: {error_msg}")
stdout_msg = stdout.decode("utf-8", errors="replace").strip()
# Rate-Limit-Fehler kommen als JSON auf stdout, nicht auf stderr
error_type = "cli_error"
rate_limit_keywords = ["hit your limit", "rate limit", "resets", "rate_limit", "overloaded"]
combined_output = f"{error_msg} {stdout_msg}".lower()
if any(kw in combined_output for kw in rate_limit_keywords):
error_type = "rate_limit"
logger.warning(f"Claude CLI Rate-Limit (Exit {process.returncode}): {stdout_msg or error_msg}")
else:
logger.error(f"Claude CLI Fehler (Exit {process.returncode}): {error_msg}")
if stdout_msg:
logger.error(f"Claude CLI stdout bei Fehler: {stdout_msg[:500]}")
raise RuntimeError(f"Claude CLI Fehler [{error_type}]: {stdout_msg or error_msg}")
raw = stdout.decode("utf-8", errors="replace").strip()
usage = ClaudeUsage()