# How It Works ## Architecture Overview ``` ┌─────────────────────────────────────────────────────────────┐ │ Your Application │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Splat Middleware │ │ │ │ • Catches unhandled exceptions │ │ │ │ • Captures request context │ │ │ │ • Collects recent logs │ │ │ └─────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ GitHub Issue │ │ • Exception type and message │ │ • Full stack trace │ │ • Request context (method, path, client IP) │ │ • Recent application logs │ │ • Error signature for deduplication │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ GitHub Action (Auto-Fix) │ │ • Triggered by "splat" label │ │ • Runs Claude Code with debugging instructions │ │ • Creates a PR with the fix │ └─────────────────────────────────────────────────────────────┘ ``` ## Error Capture When an unhandled exception occurs: 1. **Middleware intercepts** - The Splat middleware wraps your request handlers and catches any unhandled exceptions 2. **Context extraction** - HTTP method, path, and client IP are captured 3. **Log collection** - Recent log entries from Python's logging system are gathered 4. **Re-raise** - The exception is re-raised so your app's normal error handling continues ## Issue Creation The GitHub issue includes: - **Title**: `[Splat] ExceptionType in filename:line` - **Body**: - Exception details and message - Full stack trace - Request context table - Recent logs (collapsible section) - Error signature for deduplication ### Error Deduplication Splat generates a unique signature for each error based on: - Exception type - Filename where error occurred - Line number - Function name Before creating an issue, Splat searches for existing open issues with the same signature. If found, it skips creating a duplicate. ## Log Buffering Splat maintains a rolling buffer of recent log entries: - Default size: 200 entries - Attaches to Python's root logger - Captures logs from all loggers in your application - FIFO (first-in-first-out) - oldest entries are dropped when full When an error occurs, the buffered logs are included in the GitHub issue. ## Auto-Fix Workflow The GitHub Action (`.github/workflows/splat-autofix.yml`) triggers when: - An issue is opened or labeled with `splat` or `auto-fix` - Someone comments `@claude` on an issue The workflow: 1. **Checks out your code** 2. **Sets up the environment** (Python/Node dependencies) 3. **Runs Claude Code** with embedded instructions for: - Systematic debugging (find root cause before fixing) - Test-driven development (write failing test, implement fix, verify) - Verification before completion (run tests before claiming success) 4. **Creates a PR** with the fix ### Authentication The workflow supports two authentication methods: - **API Key**: Uses `ANTHROPIC_API_KEY` secret - **OAuth**: Uses `CLAUDE_OAUTH_TOKEN` secret (for Claude Code subscription) These are configured during `splat init` or `splat install-autofix`. ## Background Processing Errors are processed asynchronously in a background queue: 1. **Non-blocking** - `report()` returns immediately, error is queued 2. **Retries** - Failed API calls retry with exponential backoff (1s, 2s, 4s) 3. **Graceful degradation** - After 3 attempts, errors are logged and dropped This ensures error tracking never slows down your application. ## Payload Limits Large payloads are automatically truncated to prevent issues: - **Traceback**: Max 50,000 characters - **Log entries**: Max 500 entries (most recent kept) - **Context values**: Max 5,000 characters per value Truncated content shows `... [truncated]` indicator.