Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion app/middleware/error_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@
Global Error Handlers
"""

from flask import jsonify
from flask import jsonify, render_template, request
from werkzeug.exceptions import HTTPException
from app.utils.logger import setup_logger

logger = setup_logger(__name__)


def _wants_html():
"""Return True if the client prefers an HTML response (i.e. browser request)."""
best = request.accept_mimetypes.best_match(['text/html', 'application/json'])
return best == 'text/html'


def register_error_handlers(app):
"""Register global error handlers for the Flask app"""

Expand Down Expand Up @@ -62,6 +68,16 @@ def internal_server_error(error):
'message': 'An unexpected error occurred'
}), 500

@app.errorhandler(503)
def service_unavailable(error):
"""Serve a lightweight page for browser clients when the service is overloaded."""
if _wants_html():
return render_template('503.html'), 503
return jsonify({
'error': 'Service unavailable',
'message': 'The service is temporarily unavailable. Please try again later.'
}), 503

@app.errorhandler(HTTPException)
def handle_http_exception(error):
"""Handle all HTTP exceptions"""
Expand Down
63 changes: 63 additions & 0 deletions templates/503.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Service Temporarily Unavailable - TF Visualizer</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
background: #0f1117;
color: #e2e8f0;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 1rem;
}
.container {
max-width: 480px;
width: 100%;
text-align: center;
}
.code {
font-size: 5rem;
font-weight: 700;
color: #f59e0b;
line-height: 1;
}
h1 {
font-size: 1.25rem;
font-weight: 600;
margin: 0.75rem 0 0.5rem;
color: #f1f5f9;
}
p {
font-size: 0.95rem;
color: #94a3b8;
line-height: 1.6;
margin-bottom: 1.5rem;
}
a {
display: inline-block;
padding: 0.6rem 1.4rem;
background: #f59e0b;
color: #0f1117;
border-radius: 6px;
text-decoration: none;
font-weight: 600;
font-size: 0.9rem;
}
a:hover { background: #d97706; }
</style>
</head>
<body>
<div class="container">
<div class="code">503</div>
<h1>Service Temporarily Unavailable</h1>
<p>We're experiencing high load or performing maintenance.<br>Please try again in a moment.</p>
<a href="/">Try Again</a>
</div>
</body>
</html>
Loading