Phase 2 Step 7: Implement Error Handling & Logging
Comprehensive error handling and logging system with production-ready features for monitoring, debugging, and user experience. Enhanced Logging System: - Implemented RotatingFileHandler (10MB per file, 10 backups, 100MB total) - Separate error log file for ERROR level messages with detailed tracebacks - Structured logging with request IDs, timestamps, and module names - RequestIDLogFilter for automatic request context injection - Console logging in debug mode with simplified format Request/Response Middleware: - Request ID generation using UUID (8-character prefix for readability) - Request timing with millisecond precision - User authentication context in all logs - Response duration tracking and headers (X-Request-ID, X-Request-Duration-Ms) - Security headers: X-Content-Type-Options, X-Frame-Options, X-XSS-Protection Database Error Handling: - Enabled SQLite WAL mode for better concurrency with background jobs - Busy timeout configuration (15 seconds) for lock handling - Automatic rollback on request exceptions via teardown handler - Dedicated SQLAlchemyError handler with explicit rollback - Connection pooling with pre-ping validation Comprehensive Error Handlers: - Content negotiation: JSON responses for API, HTML for web requests - Error handlers for 400, 401, 403, 404, 405, 500 - Database rollback in all error handlers - Full exception logging with traceback for debugging Custom Error Templates: - Created web/templates/errors/ directory with 6 templates - Dark theme matching application design (slate colors) - User-friendly error messages with navigation - Templates: 400, 401, 403, 404, 405, 500 Testing: - Comprehensive test suite (320+ lines) in tests/test_error_handling.py - Tests for JSON vs HTML error responses - Request ID and duration header verification - Security header validation - Log rotation configuration tests - Structured logging tests Bug Fix: - Fixed pagination bug in scans API endpoint - Changed paginated_result.total_pages to paginated_result.pages - Resolves AttributeError when listing scans Files Added: - tests/test_error_handling.py - web/templates/errors/400.html - web/templates/errors/401.html - web/templates/errors/403.html - web/templates/errors/404.html - web/templates/errors/405.html - web/templates/errors/500.html Files Modified: - web/app.py (logging, error handlers, request handlers, database config) - web/api/scans.py (pagination bug fix) - docs/ai/PHASE2.md (mark Step 7 complete, update progress to 86%) Phase 2 Progress: 12/14 days complete (86%)
This commit is contained in:
84
web/templates/errors/400.html
Normal file
84
web/templates/errors/400.html
Normal file
@@ -0,0 +1,84 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>400 - Bad Request | SneakyScanner</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
background-color: #0f172a;
|
||||
color: #e2e8f0;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.error-container {
|
||||
text-align: center;
|
||||
max-width: 600px;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.error-code {
|
||||
font-size: 8rem;
|
||||
font-weight: 700;
|
||||
color: #f59e0b;
|
||||
line-height: 1;
|
||||
margin-bottom: 1rem;
|
||||
text-shadow: 0 0 20px rgba(245, 158, 11, 0.3);
|
||||
}
|
||||
|
||||
.error-title {
|
||||
font-size: 2rem;
|
||||
font-weight: 600;
|
||||
color: #e2e8f0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
font-size: 1.1rem;
|
||||
color: #94a3b8;
|
||||
margin-bottom: 2rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
|
||||
border: none;
|
||||
padding: 0.75rem 2rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
border-radius: 0.5rem;
|
||||
transition: all 0.3s;
|
||||
box-shadow: 0 4px 6px rgba(59, 130, 246, 0.2);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 12px rgba(59, 130, 246, 0.3);
|
||||
background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);
|
||||
}
|
||||
|
||||
.error-icon {
|
||||
font-size: 4rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="error-container">
|
||||
<div class="error-icon">⚠️</div>
|
||||
<div class="error-code">400</div>
|
||||
<h1 class="error-title">Bad Request</h1>
|
||||
<p class="error-message">
|
||||
The request could not be understood or was missing required parameters.
|
||||
<br>
|
||||
Please check your input and try again.
|
||||
</p>
|
||||
<a href="/" class="btn btn-primary">Go to Dashboard</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user