ALT Error Handling
Advanced error handling utilities for Python applications, providing decorators and context managers for consistent and robust error management.
Features
- 🎯 Consistent Error Handling: Decorators for standardized error handling across your application
- 🔄 Exception Conversion: Transform exceptions to match your application's error hierarchy
- 📝 Contextual Information: Add context to exceptions for better debugging
- 🛡️ Safe Execution: Execute functions with fallback values on error
- 🧹 Cleanup Guarantees: Ensure cleanup code runs even when errors occur
- 📊 Error Aggregation: Combine multiple errors into comprehensive error reports
- 🔗 Exception Chain Formatting: Format exception chains for logging
Installation
pip install ALT-error-handling
For development:
git clone https://github.com/Avilir/ALT-error-handling.git
cd ALT-error-handling
pip install -e ".[dev]"
Quick Start
Basic Error Handling
from alt_error_handling import handle_errors
@handle_errors(ValueError, TypeError, reraise=False, default_return=None)
def risky_function(data):
# This function might raise ValueError or TypeError
return process_data(data)
# If an error occurs, it will be logged and None will be returned
result = risky_function(invalid_data)
Adding Context to Errors
from alt_error_handling import error_context
def process_user_data(user_id, data):
with error_context("processing user data", user_id=user_id, data_size=len(data)):
# Any exception here will include the context information
validate_data(data)
transform_data(data)
save_data(user_id, data)
Core Features
1. Error Handling Decorator
The handle_errors decorator provides comprehensive error handling with logging:
from alt_error_handling import handle_errors
import logging
# Set up logging
logger = logging.getLogger(__name__)
@handle_errors(
IOError,
OSError,
reraise=True, # Re-raise after logging
log_level=logging.ERROR,
context="file operation",
logger=logger
)
def read_config(path):
with open(path) as f:
return json.load(f)
2. Exception Conversion
Transform exceptions to match your application's error hierarchy:
from alt_error_handling import convert_exceptions
class DataValidationError(Exception):
"""Application-specific validation error"""
pass
@convert_exceptions({
ValueError: DataValidationError,
TypeError: lambda e: DataValidationError(f"Invalid type: {e}"),
KeyError: lambda e: DataValidationError(f"Missing field: {e}")
})
def validate_user_input(data):
if not isinstance(data, dict):
raise TypeError("Data must be a dictionary")
if "username" not in data:
raise KeyError("username")
if not data["username"]:
raise ValueError("Username cannot be empty")
3. Safe Execution
Execute functions with fallback values:
from alt_error_handling import safe_execute
# Parse JSON with fallback to empty dict
config = safe_execute(
json.loads,
config_string,
default={},
exceptions=(json.JSONDecodeError,)
)
# Calculate with fallback
result = safe_execute(
lambda: x / y,
default=float('inf'),
exceptions=(ZeroDivisionError,)
)
4. Error Context Manager
Add debugging context to any code block:
from alt_error_handling import error_context, ErrorHandlingError
class DatabaseError(ErrorHandlingError):
"""Custom database error with context support"""
pass
def update_user(user_id, updates):
with error_context(
"updating user",
DatabaseError,
user_id=user_id,
update_fields=list(updates.keys())
):
user = db.get_user(user_id)
user.update(updates)
db.save(user)
5. Cleanup Guarantees
Ensure cleanup code runs even when errors occur:
from alt_error_handling import ensure_cleanup
def cleanup_resources():
close_connections()
release_locks()
clean_temp_files()
@ensure_cleanup(cleanup_resources)
def process_with_resources():
acquire_locks()
open_connections()
# If this fails, cleanup_resources will still run
do_processing()
6. Error Aggregation
Collect multiple errors for comprehensive error reporting:
from alt_error_handling import aggregate_errors
errors = []
for item in items:
try:
process_item(item)
except Exception as e:
errors.append(e)
if errors:
# Combine all errors into one comprehensive error
raise aggregate_errors(
errors,
message="Failed to process items",
exception_type=ProcessingError
)
7. Exception Chain Formatting
Format exception chains for logging:
from alt_error_handling import format_exception_chain
try:
risky_operation()
except Exception as e:
# Get a formatted string of the exception chain
error_details = format_exception_chain(e, include_traceback=True)
logger.error(f"Operation failed:\n{error_details}")
Best Practices
1. Consistent Error Handling Strategy
# Define application-specific errors
class AppError(ErrorHandlingError):
"""Base application error"""
pass
class ValidationError(AppError):
"""Validation error"""
pass
class ProcessingError(AppError):
"""Processing error"""
pass
# Use consistent error handling throughout
@handle_errors(Exception, reraise=True, context="data processing")
@convert_exceptions({
ValueError: ValidationError,
TypeError: ValidationError,
RuntimeError: ProcessingError
})
def process_data(data):
validate(data)
return transform(data)
2. Layered Error Handling
# Low-level function with specific error handling
@handle_errors(IOError, OSError, reraise=False, default_return=None)
def read_file(path):
with open(path) as f:
return f.read()
# High-level function with broader error handling
@handle_errors(Exception, context="processing pipeline")
def process_files(file_paths):
results = []
for path in file_paths:
with error_context("processing file", path=path):
data = read_file(path)
if data:
results.append(transform_data(data))
return results
3. Detailed Error Context
@handle_errors(Exception, reraise=True)
def complex_operation(user_id, data, options):
with error_context(
"complex operation",
user_id=user_id,
data_size=len(data),
options=options,
timestamp=datetime.now().isoformat()
):
# Multiple steps with individual context
with error_context("validation step"):
validate_input(data, options)
with error_context("processing step"):
result = process(data)
with error_context("save step"):
save_result(user_id, result)
return result
Advanced Usage
Custom Logging Function
def custom_error_logger(logger, error, context, details):
# Send to monitoring service
monitoring.send_error({
'error_type': type(error).__name__,
'error_message': str(error),
'context': context,
'function': details['function'],
'timestamp': datetime.now().isoformat()
})
# Log locally
logger.error(f"{context} failed: {error}")
@handle_errors(
Exception,
log_func=custom_error_logger,
context="critical operation"
)
def critical_operation():
# ...
Conditional Error Handling
def make_error_handler(debug_mode=False):
return handle_errors(
Exception,
reraise=debug_mode, # Reraise in debug mode
default_return=None if not debug_mode else ...,
log_level=logging.DEBUG if debug_mode else logging.ERROR
)
# Use based on configuration
@make_error_handler(debug_mode=app.config.DEBUG)
def application_function():
# ...
Testing
The library includes comprehensive tests. Run them with:
# Run all tests
pytest
# Run with coverage
pytest --cov=alt_error_handling
# Run specific test file
pytest tests/test_core.py
Development
Setup Development Environment
# Clone the repository
git clone https://github.com/Avilir/ALT-error-handling.git
cd ALT-error-handling
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install in development mode
pip install -e ".[dev]"
# Install pre-commit hooks
pre-commit install
Running Quality Checks
# Type checking
mypy src
# Linting
ruff check .
# Formatting
black .
# All checks
make check # If Makefile is available
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Author
Avi Layani
Email: alayani@redhat.com
Acknowledgments
- Inspired by error handling patterns in various Python frameworks
- Built with modern Python development best practices
- Type hints for better IDE support and code clarity
Metadata
Release files for ALT-error-handling 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| alt_error_handling-0.1.0.tar.gz | 13.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| alt_error_handling-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 23.4 kB
Release files / alt_error_handling-0.1.0.tar.gz
| Download URL | alt_error_handling-0.1.0.tar.gz |
|---|---|
| Size | 13.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6d3f43e26d952a0e949d580c528a8f73f2d3c88569455870082b60b59afb8332
|
|
BLAKE2b-256 checksum How to use checksums |
67014423bb012972b9c6d8ee20918cdd90da0e58a0d47bace91fa787001579f7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Release files / alt_error_handling-0.1.0-py3-none-any.whl
| Download URL | alt_error_handling-0.1.0-py3-none-any.whl |
|---|---|
| Size | 9.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fb989d2115d2bca7cc4c64af15208063612245f0f02bfd0a60f4cebee0c69f32
|
|
BLAKE2b-256 checksum How to use checksums |
5a8ff7392febc7db4961185511a028008c94de4c5ea9fd2308dbaeaef4488303
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|