From 7b3150a69d83e8c8fed3d5e2d8d50233d267f5dc Mon Sep 17 00:00:00 2001 From: Matt Van Horn Date: Fri, 23 Jan 2026 16:54:31 -0800 Subject: [PATCH] Add --debug flag for verbose logging - Add LAST30DAYS_DEBUG env var / --debug flag - Log HTTP requests, responses, and errors - Show API error details when debug enabled - Helps diagnose API failures Usage: python3 last30days.py "topic" --debug Co-Authored-By: Claude Opus 4.5 --- scripts/last30days.py | 14 ++++++++++++++ scripts/lib/http.py | 20 ++++++++++++++++++++ scripts/lib/openai_reddit.py | 11 ++++++++++- scripts/lib/xai_x.py | 11 ++++++++++- 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/scripts/last30days.py b/scripts/last30days.py index ceae026..f72270d 100644 --- a/scripts/last30days.py +++ b/scripts/last30days.py @@ -11,10 +11,12 @@ Options: --sources=MODE Source selection: auto|reddit|x|both (default: auto) --quick Faster research with fewer sources (8-12 each) --deep Comprehensive research with more sources (50-70 Reddit, 40-60 X) + --debug Enable verbose debug logging """ import argparse import json +import os import sys from datetime import datetime, timezone from pathlib import Path @@ -190,9 +192,21 @@ def main(): action="store_true", help="Comprehensive research with more sources (50-70 Reddit, 40-60 X)", ) + parser.add_argument( + "--debug", + action="store_true", + help="Enable verbose debug logging", + ) args = parser.parse_args() + # Enable debug logging if requested + if args.debug: + os.environ["LAST30DAYS_DEBUG"] = "1" + # Re-import http to pick up debug flag + from lib import http as http_module + http_module.DEBUG = True + # Determine depth if args.quick and args.deep: print("Error: Cannot use both --quick and --deep", file=sys.stderr) diff --git a/scripts/lib/http.py b/scripts/lib/http.py index 3af767f..a8e15be 100644 --- a/scripts/lib/http.py +++ b/scripts/lib/http.py @@ -1,6 +1,8 @@ """HTTP utilities for last30days skill (stdlib only).""" import json +import os +import sys import time import urllib.error import urllib.request @@ -8,6 +10,14 @@ from typing import Any, Dict, Optional from urllib.parse import urlencode DEFAULT_TIMEOUT = 30 +DEBUG = os.environ.get("LAST30DAYS_DEBUG", "").lower() in ("1", "true", "yes") + + +def log(msg: str): + """Log debug message to stderr.""" + if DEBUG: + sys.stderr.write(f"[DEBUG] {msg}\n") + sys.stderr.flush() MAX_RETRIES = 3 RETRY_DELAY = 1.0 USER_AGENT = "last30days-skill/1.0 (Claude Code Skill)" @@ -55,11 +65,16 @@ def request( req = urllib.request.Request(url, data=data, headers=headers, method=method) + log(f"{method} {url}") + if json_data: + log(f"Payload keys: {list(json_data.keys())}") + last_error = None for attempt in range(retries): try: with urllib.request.urlopen(req, timeout=timeout) as response: body = response.read().decode('utf-8') + log(f"Response: {response.status} ({len(body)} bytes)") return json.loads(body) if body else {} except urllib.error.HTTPError as e: body = None @@ -67,6 +82,9 @@ def request( body = e.read().decode('utf-8') except: pass + log(f"HTTP Error {e.code}: {e.reason}") + if body: + log(f"Error body: {body[:500]}") last_error = HTTPError(f"HTTP {e.code}: {e.reason}", e.code, body) # Don't retry client errors (4xx) except rate limits @@ -76,10 +94,12 @@ def request( if attempt < retries - 1: time.sleep(RETRY_DELAY * (attempt + 1)) except urllib.error.URLError as e: + log(f"URL Error: {e.reason}") last_error = HTTPError(f"URL Error: {e.reason}") if attempt < retries - 1: time.sleep(RETRY_DELAY * (attempt + 1)) except json.JSONDecodeError as e: + log(f"JSON decode error: {e}") last_error = HTTPError(f"Invalid JSON response: {e}") raise last_error diff --git a/scripts/lib/openai_reddit.py b/scripts/lib/openai_reddit.py index 40c10ba..305750c 100644 --- a/scripts/lib/openai_reddit.py +++ b/scripts/lib/openai_reddit.py @@ -2,10 +2,17 @@ import json import re +import sys from typing import Any, Dict, List, Optional from . import http + +def _log_error(msg: str): + """Log error to stderr.""" + sys.stderr.write(f"[REDDIT ERROR] {msg}\n") + sys.stderr.flush() + OPENAI_RESPONSES_URL = "https://api.openai.com/v1/responses" # Depth configurations: (min, max) threads to request @@ -120,7 +127,9 @@ def parse_reddit_response(response: Dict[str, Any]) -> List[Dict[str, Any]]: if "error" in response and response["error"]: error = response["error"] err_msg = error.get("message", str(error)) if isinstance(error, dict) else str(error) - print(f"[REDDIT ERROR] OpenAI API error: {err_msg}", flush=True) + _log_error(f"OpenAI API error: {err_msg}") + if http.DEBUG: + _log_error(f"Full error response: {json.dumps(response, indent=2)[:1000]}") return items # Try to find the output text diff --git a/scripts/lib/xai_x.py b/scripts/lib/xai_x.py index 2a0fe25..badd4d3 100644 --- a/scripts/lib/xai_x.py +++ b/scripts/lib/xai_x.py @@ -2,10 +2,17 @@ import json import re +import sys from typing import Any, Dict, List, Optional from . import http + +def _log_error(msg: str): + """Log error to stderr.""" + sys.stderr.write(f"[X ERROR] {msg}\n") + sys.stderr.flush() + # xAI uses chat completions endpoint XAI_CHAT_URL = "https://api.x.ai/v1/chat/completions" @@ -129,7 +136,9 @@ def parse_x_response(response: Dict[str, Any]) -> List[Dict[str, Any]]: if "error" in response and response["error"]: error = response["error"] err_msg = error.get("message", str(error)) if isinstance(error, dict) else str(error) - print(f"[X ERROR] xAI API error: {err_msg}", flush=True) + _log_error(f"xAI API error: {err_msg}") + if http.DEBUG: + _log_error(f"Full error response: {json.dumps(response, indent=2)[:1000]}") return items # Try to find the output text