Skip to main content

AI-optimized exception summarization that automatically sends to LLMs

Project description

errzip

AI-optimized exception summarization for Python

errzip captures Python exceptions, creates compact structured JSON summaries optimized for small AI context windows, and ALWAYS sends them to an LLM (Ollama by default, OpenAI, or Claude) for instant analysis.

Features

  • 🎯 Automatic LLM Analysis: Every exception is automatically sent to your configured LLM
  • 📊 Structured JSON Output: Machine-readable format optimized for AI tools
  • 🔍 Smart Frame Selection: Identifies the most relevant stack frame (skips stdlib)
  • 💡 Built-in Heuristics: Common error patterns mapped to likely causes
  • 🔌 Multiple LLM Backends: Supports Ollama (default), OpenAI, and Claude
  • 🛡️ Zero-Crash Design: Never fails your program, even if analysis fails
  • 📦 Minimal Dependencies: Only requires requests beyond stdlib

Installation

pip install errzip

Or install from source:

git clone https://github.com/yourusername/errzip.git
cd errzip
pip install -e .

Quick Start

Option 1: Global Exception Hook (Catch All Unhandled Exceptions)

import errzip

# Install the hook - all unhandled exceptions will be analyzed
errzip.install_excepthook()

# Any unhandled exception will be caught, summarized, and sent to LLM
def buggy_function():
    return {}['missing_key']

buggy_function()  # Exception analyzed by AI automatically

Option 2: Decorator (Specific Functions)

import errzip

@errzip.summarize_exceptions(reraise=True)
def risky_operation(filename):
    with open(filename) as f:
        return f.read()

# Exception will be summarized and sent to AI before re-raising
risky_operation('/nonexistent/file.txt')

Option 3: Manual (Programmatic Control)

import errzip

try:
    result = 10 / 0
except Exception as e:
    summary = errzip.summarize_exception(e)
    print(f"Error: {summary.error_type}")
    print(f"Cause: {summary.likely_cause}")
    print(f"Suggestions: {summary.suggestions}")

Configuration

Configure via environment variables:

Choose Your LLM Provider

# Ollama (default, free, runs locally)
export WORKING_AI=ollama
export OLLAMA_BASE_URL=http://127.0.0.1:11434
export OLLAMA_MODEL=llama3.1

# OpenAI
export WORKING_AI=openai
export OPENAI_API_KEY=sk-...
export OPENAI_MODEL=gpt-4o-mini

# Claude (Anthropic)
export WORKING_AI=claude
export ANTHROPIC_API_KEY=sk-ant-...
export CLAUDE_MODEL=claude-3-5-sonnet-latest

# Disable AI (JSON output only, no LLM calls)
export WORKING_AI=none

General Settings

export ERRSUM_AI_TIMEOUT=12.0      # Timeout for LLM calls (seconds)
export ERRSUM_AI_MAX_CHARS=20000   # Max JSON size before truncation

Output Format

Every exception generates two outputs to STDERR:

1. Human-Readable One-Liner

[errzip] builtins.KeyError: 'missing_key' at script.py:15 in buggy_function | cause: Dictionary key does not exist

2. Machine-Readable JSON

===ERRSUM_JSON_BEGIN===
{
  "error_type": "builtins.KeyError",
  "message": "'missing_key'",
  "top_frame": {
    "file": "script.py",
    "line": 15,
    "function": "buggy_function",
    "code": "return x['missing_key']"
  },
  "stack": [...],
  "likely_cause": "Dictionary key does not exist",
  "suggestions": [
    "Verify key exists before access",
    "Use .get() with default",
    "Check data structure"
  ],
  "env": {
    "python_version": "3.11.5",
    "platform": "macOS-14.0-arm64",
    "cwd": "/Users/you/project"
  },
  "dependencies": {...},
  "raw_traceback": "..."
}
===ERRSUM_JSON_END===

3. AI Analysis (ALWAYS Generated)

===ERRSUM_AI_BEGIN===
Error: KeyError accessing missing dictionary key
Location: script.py:15 in buggy_function
Likely cause: Attempting to access a key that doesn't exist in the dictionary
Quick checks:
  - Verify the key 'missing_key' should exist
  - Check if dictionary was populated correctly
  - Add defensive key checking
Fast fix: Use x.get('missing_key', default_value)
===ERRSUM_AI_END===

Why errzip?

Traditional Error Messages

Traceback (most recent call last):
  File "script.py", line 42, in <module>
    process_data()
  File "script.py", line 38, in process_data
    return data['result']['value']
KeyError: 'result'

With errzip

[errzip] builtins.KeyError: 'result' at script.py:38 in process_data | cause: Dictionary key does not exist

===ERRSUM_AI_BEGIN===
Error: Missing 'result' key in dictionary
Location: script.py:38 in process_data
Likely cause: API response doesn't contain expected 'result' key
Quick checks:
  - Verify API endpoint is returning correct structure
  - Check if request completed successfully
  - Add response validation
Fast fix: Use data.get('result', {}).get('value') or validate response first
===ERRSUM_AI_END===

Built-in Heuristics

errzip recognizes common error patterns:

  • ImportError/ModuleNotFoundError → Missing dependency
  • KeyError → Dictionary key doesn't exist
  • AttributeError → Missing attribute or None access
  • FileNotFoundError → Wrong path or working directory
  • PermissionError → Insufficient OS permissions
  • TypeError (positional arguments) → Function arity mismatch
  • ValueError (invalid literal) → Parsing failure
  • TimeoutError → Operation exceeded time limit
  • SSL errors → Certificate validation issues
  • MemoryError → Out of memory

API Reference

install_excepthook()

Installs global exception hook to catch all unhandled exceptions.

@summarize_exceptions(reraise=True)

Decorator to summarize exceptions in specific functions.

  • reraise=True: Re-raises exception after summarizing
  • reraise=False: Swallows exception, returns None

summarize_exception(exc: BaseException) -> ExceptionSummary

Manually create a summary of an exception. Returns ExceptionSummary dataclass.

Use Cases

  • Development: Get instant AI insights on errors as you code
  • Production Monitoring: Parse JSON logs for automated error analysis
  • CI/CD: Extract structured error data from test failures
  • Learning: Understand why exceptions happen with AI explanations
  • Cost Optimization: Minimize LLM token usage with compact JSON format

How It Works

  1. Exception Captured: Via hook, decorator, or manual call
  2. Stack Analysis: Extracts frames, identifies user code vs stdlib
  3. Heuristics Applied: Maps error type/message to likely causes
  4. JSON Generation: Creates compact, structured summary (~2-5KB typical)
  5. LLM Call: ALWAYS sends to configured LLM (unless WORKING_AI=none)
  6. Output: Emits human line, JSON, and AI analysis to STDERR

Safety & Security

  • ✅ Never crashes your program (all operations wrapped)
  • ✅ No secrets logged (only necessary env vars used)
  • ✅ Network failures handled gracefully
  • ✅ Works offline (if WORKING_AI=none)

Requirements

  • Python 3.8+
  • requests library

License

MIT

Contributing

Contributions welcome! Please open an issue or PR.

Roadmap

  • Async LLM calls (non-blocking)
  • Custom heuristics plugins
  • More LLM providers (Gemini, etc.)
  • Performance profiling data in summary
  • Integration with observability platforms

Built for developers who want AI-powered error analysis without the overhead.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

errzip-0.1.0.tar.gz (22.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

errzip-0.1.0-py3-none-any.whl (11.9 kB view details)

Uploaded Python 3

File details

Details for the file errzip-0.1.0.tar.gz.

File metadata

  • Download URL: errzip-0.1.0.tar.gz
  • Upload date:
  • Size: 22.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for errzip-0.1.0.tar.gz
Algorithm Hash digest
SHA256 424ca3399f5befff7fc4600d80ca1a6759b1705a2faeacecd2db9efe9b61b9b3
MD5 9add462a20f56325bb8cea543effe32a
BLAKE2b-256 7ccf02e1065db2e261432c4e5d7d382c3034d228fb8c98d1063f8ba7fe6ef154

See more details on using hashes here.

File details

Details for the file errzip-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: errzip-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 11.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for errzip-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3cd7765e006e217d91005292d7e48a97f787802c402dcc9612f7ba15674f848a
MD5 b43ef0bd6ba133e0ba14716ce1c88ac2
BLAKE2b-256 64a81ede77681a287c6bca7a20a71a0ee92f7585014b2180ccc3188428632d18

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page