Files
v2-Docker/v2_adminpanel/ERROR_HANDLING_GUIDE.md
Claude Project Manager 0d7d888502 Initial commit
2025-07-05 17:51:16 +02:00

456 Zeilen
9.5 KiB
Markdown

# Error Handling Guide
## Overview
This guide describes the error handling system implemented in the v2_adminpanel application. The system provides:
- Centralized error handling with custom exception hierarchy
- Input validation framework
- Structured logging
- Monitoring and alerting
- Consistent error responses
## Architecture
### 1. Custom Exception Hierarchy
```
BaseApplicationException
├── ValidationException
│ ├── InputValidationError
│ ├── BusinessRuleViolation
│ └── DataIntegrityError
├── AuthenticationException
│ ├── InvalidCredentialsError
│ ├── SessionExpiredError
│ └── InsufficientPermissionsError
├── DatabaseException
│ ├── ConnectionError
│ ├── QueryError
│ └── TransactionError
├── ExternalServiceException
│ ├── APIError
│ └── TimeoutError
└── ResourceException
├── ResourceNotFoundError
├── ResourceConflictError
└── ResourceLimitExceeded
```
### 2. Core Components
- **core/exceptions.py**: Custom exception classes
- **core/error_handlers.py**: Global error handlers and decorators
- **core/validators.py**: Input validation framework
- **core/logging_config.py**: Structured logging setup
- **core/monitoring.py**: Error metrics and alerting
- **middleware/error_middleware.py**: Request-level error handling
## Usage Examples
### 1. Raising Custom Exceptions
```python
from core.exceptions import (
InputValidationError,
ResourceNotFoundError,
BusinessRuleViolation
)
# Validation error
if not email_is_valid:
raise InputValidationError(
field='email',
message='Invalid email format',
value=email_value,
expected_type='email'
)
# Resource not found
user = db.get_user(user_id)
if not user:
raise ResourceNotFoundError(
resource_type='User',
resource_id=user_id
)
# Business rule violation
if active_licenses >= license_limit:
raise BusinessRuleViolation(
rule='license_limit',
message='License limit exceeded',
context={
'current': active_licenses,
'limit': license_limit
}
)
```
### 2. Using Error Decorators
```python
from core.error_handlers import handle_errors, validate_request
from core.validators import validate
@handle_errors(
catch=(psycopg2.Error,),
message='Database operation failed',
user_message='Datenbankfehler aufgetreten',
redirect_to='admin.dashboard'
)
def update_customer(customer_id):
# Database operations
pass
@validate_request(
required_fields={
'email': str,
'age': int,
'active': bool
}
)
def create_user():
# Request data is validated
pass
@validate({
'email': {
'type': 'email',
'required': True
},
'password': {
'type': 'password',
'required': True
},
'age': {
'type': 'integer',
'required': True,
'min_value': 18,
'max_value': 120
}
})
def register_user():
# Access validated data
data = request.validated_data
# Use data safely
```
### 3. Input Validation
```python
from core.validators import Validators
# Email validation
email = Validators.email(user_input, field_name='email')
# Phone validation
phone = Validators.phone(user_input, field_name='phone')
# License key validation
license_key = Validators.license_key(user_input)
# Integer with constraints
age = Validators.integer(
user_input,
field_name='age',
min_value=0,
max_value=150
)
# String with constraints
username = Validators.string(
user_input,
field_name='username',
min_length=3,
max_length=50,
safe_only=True
)
# Password validation
password = Validators.password(user_input)
# Custom enum validation
status = Validators.enum(
user_input,
field_name='status',
allowed_values=['active', 'inactive', 'pending']
)
```
### 4. Error Context Manager
```python
from core.error_handlers import ErrorContext
with ErrorContext(
operation='create_license',
resource_type='License',
resource_id=license_key
):
# Operations that might fail
db.insert_license(license_data)
# Errors are automatically logged with context
```
### 5. Logging
```python
from core.logging_config import get_logger, log_error, log_security_event
logger = get_logger(__name__)
# Standard logging
logger.info('User created', extra={
'user_id': user.id,
'email': user.email
})
# Error logging
try:
risky_operation()
except Exception as e:
log_error(
logger,
'Risky operation failed',
error=e,
user_id=user.id,
operation='risky_operation'
)
# Security event logging
log_security_event(
'INVALID_LOGIN_ATTEMPT',
'Multiple failed login attempts',
username=username,
ip_address=request.remote_addr,
attempt_count=5
)
```
## Error Response Format
### JSON Responses (API)
```json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input provided",
"timestamp": "2024-01-15T10:30:00Z",
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"details": {
"field": "email",
"value": "invalid-email",
"expected_type": "email"
}
}
}
```
### HTML Responses
- User-friendly error messages
- Error code and request ID for support
- Helpful suggestions for resolution
- Navigation options (back, dashboard, retry)
## Monitoring and Alerts
### Metrics Exposed
- `app_errors_total`: Total error count by code, status, endpoint
- `app_error_rate`: Errors per minute by error code
- `app_validation_errors_total`: Validation errors by field
- `app_auth_failures_total`: Authentication failures
- `app_database_errors_total`: Database errors
- `app_request_duration_seconds`: Request duration histogram
### Alert Thresholds
- Error rate > 10/min: Critical alert
- Auth failure rate > 5/min: Security alert
- DB error rate > 3/min: Infrastructure alert
- Response time 95th percentile > 2s: Performance alert
### Accessing Metrics
- Prometheus metrics: `/metrics`
- Active alerts: `/api/alerts`
## Best Practices
### 1. Always Use Specific Exceptions
```python
# Bad
raise Exception("User not found")
# Good
raise ResourceNotFoundError('User', user_id)
```
### 2. Provide Context
```python
# Bad
raise ValidationException("Invalid data")
# Good
raise InputValidationError(
field='email',
message='Email domain not allowed',
value=email,
expected_type='corporate_email'
)
```
### 3. Handle Database Errors
```python
# Bad
result = db.execute(query)
# Good
try:
result = db.execute(query)
except psycopg2.IntegrityError as e:
if e.pgcode == '23505':
raise DataIntegrityError(
entity='User',
constraint='unique_email',
message='Email already exists'
)
raise
```
### 4. Validate Early
```python
# Bad
def process_order(data):
# Process without validation
total = data['quantity'] * data['price']
# Good
@validate({
'quantity': {'type': 'integer', 'min_value': 1},
'price': {'type': 'float', 'min_value': 0}
})
def process_order():
data = request.validated_data
total = data['quantity'] * data['price']
```
### 5. Log Security Events
```python
# Failed login attempts
log_security_event(
'LOGIN_FAILURE',
f'Failed login for user {username}',
username=username,
ip_address=request.remote_addr
)
# Suspicious activity
log_security_event(
'SUSPICIOUS_ACTIVITY',
'Rapid API requests detected',
ip_address=request.remote_addr,
request_count=count,
time_window=60
)
```
## Migration Guide
### Converting Existing Error Handling
1. **Replace generic exceptions**:
```python
# Old
except Exception as e:
flash(f"Error: {str(e)}", "error")
return redirect(url_for('admin.dashboard'))
# New
except DatabaseException as e:
# Already handled by global handler
raise
```
2. **Update validation**:
```python
# Old
email = request.form.get('email')
if not email or '@' not in email:
flash("Invalid email", "error")
return redirect(request.url)
# New
from core.validators import Validators
try:
email = Validators.email(request.form.get('email'))
except InputValidationError as e:
# Handled automatically
raise
```
3. **Use decorators**:
```python
# Old
@app.route('/api/user', methods=['POST'])
def create_user():
try:
# validation code
# database operations
except Exception as e:
return jsonify({'error': str(e)}), 500
# New
@app.route('/api/user', methods=['POST'])
@validate({
'email': {'type': 'email', 'required': True},
'name': {'type': 'string', 'required': True, 'min_length': 2}
})
def create_user():
data = request.validated_data
# Use validated data directly
```
## Testing
Run the test suite:
```bash
pytest v2_adminpanel/tests/test_error_handling.py -v
```
Test coverage includes:
- Exception creation and properties
- Error handler responses (JSON/HTML)
- Validation functions
- Decorators
- Monitoring and metrics
- Alert generation
## Troubleshooting
### Common Issues
1. **Import errors**: Ensure you import from `core` package
2. **Validation not working**: Check decorator order (validate must be closest to function)
3. **Logs not appearing**: Verify LOG_LEVEL environment variable
4. **Metrics missing**: Ensure prometheus_client is installed
### Debug Mode
In development, set:
```python
app.config['DEBUG'] = True
```
This will:
- Include detailed error information
- Show stack traces
- Log to console with readable format