Friendly explanations for Python errors
Project description
๐ฏ errfriendly
Friendly, human-readable explanations for Python exceptions โ now with AI-powered contextual understanding!
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:
- Report bugs: Open an issue describing the problem
- Suggest features: Open an issue with your idea
- 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4e6101e70fbfb679243044b5b14ea6cb2b7d25b11afe6963e4b2e894dc05cc64
|
|
| MD5 |
1604268e61f4eef55c10052c4f98cbad
|
|
| BLAKE2b-256 |
47161a25cec0bfe153fa98490a07b9a6fac56fa4505fa3665cea6ef01b48e27b
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3a9fafd0d314a23c6ed0921c757565d4b9ceb21cbdacc2b1d0b1530b90f7d3eb
|
|
| MD5 |
a5d0dde2932613d442c8cfeb775c53fb
|
|
| BLAKE2b-256 |
7b16ee460882364949071b33d6d36d1aaffd6fbb5e903a30132410cc1a437420
|