Skip to main content

Friendly explanations for Python errors

Project description

๐ŸŽฏ errfriendly

Friendly, human-readable explanations for Python exceptions โ€” now with AI-powered contextual understanding!

Python 3.8+ License: MIT PyPI version

errfriendly transforms cryptic Python error messages into clear, actionable explanations. Version 3.0 introduces AI-powered contextual analysis and exception chain visualization for an intelligent debugging assistant experience.


โœจ What's New in v3.0

  • ๐Ÿค– AI-Powered Explanations: Get context-aware, personalized error explanations
  • ๐Ÿ”— Exception Chain Analysis: Visualize and understand __cause__ and __context__ chains
  • ๐Ÿ  Local-First AI: Privacy-first with Ollama support (no data leaves your machine)
  • โ˜๏ธ Cloud AI Fallback: OpenAI, Anthropic, and Gemini support (opt-in)
  • ๐ŸŽš๏ธ Explanation Depth: Beginner, Intermediate, or Expert level explanations
  • ๐Ÿ”’ Zero Breaking Changes: Existing v2.x code works unchanged

โœจ Features

  • ๐Ÿ” Clear Explanations: Understand what went wrong in plain English
  • ๐Ÿ’ก Actionable Suggestions: Get step-by-step guidance on how to fix common errors
  • ๐Ÿค– AI Analysis: Deep contextual understanding of your code (optional)
  • ๐Ÿ”— Chain Visualization: Map exception causes into debugging stories
  • ๐ŸŽจ Colorful Output: ANSI colors in terminal for better readability
  • ๐Ÿ“ Logging Support: Optionally log exceptions to a file
  • ๐ŸŽฏ Zero Dependencies: Core package requires no external packages
  • โšก Easy Integration: Just two lines of code to get started
  • ๐Ÿ”ง Configurable: Extensive customization options
  • ๐Ÿ“ฆ 23+ Exception Types: Covers all common Python exceptions

๐Ÿ“ฆ Installation

# Core package (zero dependencies)
pip install errfriendly

# With AI features
pip install errfriendly[ai-local]    # Ollama support
pip install errfriendly[ai-openai]   # OpenAI support
pip install errfriendly[ai-all]      # All AI backends

For development installation:

git clone https://github.com/infinawaz/errfriendly.git
cd errfriendly
pip install -e ".[dev]"

๐Ÿš€ Quickstart

Basic Usage (v2.x Compatible)

import errfriendly

# Enable friendly error messages
errfriendly.install()

# That's it! Now all exceptions will show friendly explanations.

AI-Powered Explanations (v3.0)

import errfriendly

# Install the exception hook
errfriendly.install()

# Enable AI with local LLM (Ollama)
errfriendly.enable_ai(
    backend="local",
    model="codellama",
    explain_depth="intermediate"
)

# Or use OpenAI
errfriendly.enable_ai(
    backend="openai",
    api_key="sk-...",  # Or set OPENAI_API_KEY env var
    explain_depth="beginner"
)

Fine-Grained Configuration

errfriendly.configure(
    ai_threshold=0.7,           # Confidence threshold for caching
    max_context_lines=15,       # Lines of code to analyze
    include_variable_values=True,
    privacy_mode="local_only",  # or "allow_cloud"
    show_confidence=True,       # Show AI confidence scores
    show_chain_analysis=True,   # Show exception chain maps
)

๐Ÿ“ธ Before & After

Before (Standard Python)

Traceback (most recent call last):
  File "example.py", line 3, in <module>
    result = data[0]
TypeError: 'NoneType' object is not subscriptable

๐Ÿ˜• "What does subscriptable even mean?"

After (With errfriendly + AI)

Traceback (most recent call last):
  File "example.py", line 3, in <module>
    result = data[0]
TypeError: 'NoneType' object is not subscriptable

======================================================================
๐Ÿค– AI-POWERED EXPLANATION (Confidence: 92%)
======================================================================

## ๐Ÿค” What Happened?
You tried to access index `[0]` on the variable `data`, but `data` is `None`.
Looking at your code, `data` was assigned `None` on line 2.

## ๐Ÿ” Root Cause Analysis
- Primary issue: Accessing an index on a None value
- Contributing factors: Missing null check before indexing
- Confidence: High

## ๐Ÿ› ๏ธ How to Fix

### Option 1: Quick Fix (Immediate)
```python
if data is not None:
    result = data[0]

Option 2: Robust Solution (Recommended)

result = data[0] if data else default_value

Option 3: Prevent Future Occurrences

def get_first_item(data: list | None) -> Any:
    if not data:
        raise ValueError("data cannot be empty or None")
    return data[0]

====================================================================== ๐Ÿ“ Quick Reference (Static):

๐Ÿ“› TypeError: Trying to index None ...


---

## ๐Ÿ”— Exception Chain Analysis

When exceptions are chained (using `raise ... from ...`), errfriendly visualizes the chain:

```python
try:
    user = db.get_user(user_id)  # KeyError
except KeyError as e:
    raise ValueError("User not found") from e

Output:

======================================================================
๐Ÿ”— EXCEPTION CHAIN ANALYSIS
======================================================================

๐Ÿ•ต๏ธ Exception Investigation Map:

[Primary Error] ValueError: User not found
    โ†ณ Caused by: [KeyError] 'user_id'

๐Ÿ“– Story:
(1) First, a KeyError occurred: "'user_id'" โ†’ 
(2) which caused a ValueError: "User not found"

๐Ÿ”ง Fix Strategy:
Focus on the underlying KeyError: "'user_id'". 
The ValueError is just a wrapper.

๐ŸŽ›๏ธ Configuration Options

AI Backend Options

Backend Description Requirements
local / ollama Local LLM via Ollama Ollama running locally
openai OpenAI API OPENAI_API_KEY env var
anthropic Anthropic Claude ANTHROPIC_API_KEY env var
gemini Google Gemini GOOGLE_API_KEY env var

Explanation Depth

Level Description
beginner ELI5 style, simple language, explains jargon
intermediate Standard developer explanations (default)
expert Deep technical details, CPython internals

All Configuration Options

errfriendly.configure(
    # AI Settings
    ai_threshold=0.7,           # Cache confidence threshold (0.0-1.0)
    ai_timeout=10.0,            # AI request timeout (seconds)
    max_requests_per_minute=10, # Rate limiting
    
    # Context Collection
    max_context_lines=15,       # Lines of code to include
    include_variable_values=True,
    collect_git_changes=False,  # Include git diff
    
    # Privacy & Safety
    privacy_mode="local_only",  # "local_only" or "allow_cloud"
    
    # Output
    explanation_style="bullet_points",  # or "narrative", "stepwise"
    show_confidence=True,
    show_chain_analysis=True,
)

๐Ÿ“‹ Supported Exception Types

errfriendly provides friendly explanations for:

Exception Common Causes
TypeError Wrong type operations, None subscripting, not callable
ValueError Invalid conversions, unpacking issues
IndexError List/tuple/string index out of range
KeyError Missing dictionary keys
AttributeError Accessing non-existent attributes
NameError Undefined variables
ImportError Failed imports
ModuleNotFoundError Missing modules
ZeroDivisionError Division by zero
FileNotFoundError Missing files
PermissionError Access denied
RecursionError Infinite recursion
SyntaxError Invalid syntax
UnicodeDecodeError Encoding issues
UnicodeEncodeError Encoding issues
OverflowError Number too large
MemoryError Out of memory
StopIteration Iterator exhausted
AssertionError Failed assertions
NotImplementedError Unimplemented features
KeyboardInterrupt User interruption (Ctrl+C)
TimeoutError Operation timeouts
ConnectionError Network connection failures

Plus a fallback handler for any other exception types!


๐Ÿ› ๏ธ Advanced Usage

Programmatic Access

from errfriendly import get_friendly_message
from errfriendly.context_collector import ContextCollector
from errfriendly.exception_graph import ExceptionChainAnalyzer

# Get a friendly message directly
message = get_friendly_message(TypeError, TypeError("'int' object is not callable"))
print(message)

# Analyze exception context
collector = ContextCollector()
try:
    1 / 0
except:
    import sys
    context = collector.collect(*sys.exc_info())
    print(f"Detected patterns: {context.detected_patterns}")

# Analyze exception chains
analyzer = ExceptionChainAnalyzer()
try:
    try:
        raise KeyError("original")
    except KeyError as e:
        raise ValueError("wrapper") from e
except:
    chain = analyzer.analyze(*sys.exc_info())
    print(analyzer.generate_narrative(chain))

Integration with Logging

import errfriendly
import logging

# Install with file logging
errfriendly.install(log_file="errors.log")

In Jupyter Notebooks

# Works in Jupyter too!
import errfriendly
errfriendly.install()
errfriendly.enable_ai(backend="local")

# Exceptions in cells will show AI-powered explanations

๐Ÿงช Running Tests

# Install development dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run tests with coverage
pytest --cov=errfriendly --cov-report=html

๐Ÿ—บ๏ธ Roadmap

v3.0.0 โœ… (Current)

  • AI-powered contextual explanations
  • Exception chain analysis and visualization
  • Multiple AI backends (Ollama, OpenAI, Anthropic, Gemini)
  • Explanation depth levels
  • Privacy-first design

v3.1.0 (Planned)

  • IDE integrations (VS Code extension)
  • Custom prompt templates
  • Framework-specific patterns (Django, FastAPI, etc.)
  • Async/await chain analysis

v4.0.0 (Goal)

  • Interactive debugging assistant
  • Code fix suggestions with auto-apply
  • Learning from user feedback
  • Multi-language support

๐Ÿค Contributing

Contributions are welcome! Here's how you can help:

  1. Report bugs: Open an issue describing the problem
  2. Suggest features: Open an issue with your idea
  3. Submit PRs: Fork, make changes, and submit a pull request

Development Setup

git clone https://github.com/infinawaz/errfriendly.git
cd errfriendly
pip install -e ".[dev,ai-all]"
pytest

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


๐Ÿ’– Acknowledgments

  • Inspired by the Python community's focus on developer experience
  • Thanks to all contributors who help make error messages friendlier

Made with โค๏ธ for Python developers everywhere

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

errfriendly-3.0.0.tar.gz (45.4 kB view details)

Uploaded Source

Built Distribution

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

errfriendly-3.0.0-py3-none-any.whl (38.4 kB view details)

Uploaded Python 3

File details

Details for the file errfriendly-3.0.0.tar.gz.

File metadata

  • Download URL: errfriendly-3.0.0.tar.gz
  • Upload date:
  • Size: 45.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for errfriendly-3.0.0.tar.gz
Algorithm Hash digest
SHA256 4e6101e70fbfb679243044b5b14ea6cb2b7d25b11afe6963e4b2e894dc05cc64
MD5 1604268e61f4eef55c10052c4f98cbad
BLAKE2b-256 47161a25cec0bfe153fa98490a07b9a6fac56fa4505fa3665cea6ef01b48e27b

See more details on using hashes here.

File details

Details for the file errfriendly-3.0.0-py3-none-any.whl.

File metadata

  • Download URL: errfriendly-3.0.0-py3-none-any.whl
  • Upload date:
  • Size: 38.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for errfriendly-3.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3a9fafd0d314a23c6ed0921c757565d4b9ceb21cbdacc2b1d0b1530b90f7d3eb
MD5 a5d0dde2932613d442c8cfeb775c53fb
BLAKE2b-256 7b16ee460882364949071b33d6d36d1aaffd6fbb5e903a30132410cc1a437420

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