fix: keep shell route errors html

This commit is contained in:
Michael Lam
2026-05-07 11:23:08 -07:00
committed by nesquena-hermes
parent 740e5412a5
commit 78c09e1fd9
3 changed files with 99 additions and 10 deletions
+41 -10
View File
@@ -2509,6 +2509,34 @@ def _handle_plugins(handler, parsed) -> bool:
)
_SHELL_ERROR_HTML = """<!doctype html>
<html lang=\"en\">
<head>
<meta charset=\"utf-8\">
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
<title>Hermes is restarting</title>
</head>
<body style=\"margin:0;padding:2rem;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;background:#111827;color:#e5e7eb;\">
<main style=\"max-width:40rem;margin:10vh auto;line-height:1.5;\">
<h1 style=\"font-size:1.5rem;margin:0 0 0.75rem;\">Hermes is restarting…</h1>
<p style=\"margin:0;color:#cbd5e1;\">The WebUI shell could not load cleanly. Refresh in a moment if this page does not update automatically.</p>
</main>
</body>
</html>"""
def _serve_shell_unavailable(handler, exc: Exception) -> bool:
"""Return HTML for shell-route failures so `/` never renders JSON."""
logger.warning("Failed to serve WebUI shell route: %s", exc)
t(
handler,
_SHELL_ERROR_HTML,
status=503,
content_type="text/html; charset=utf-8",
)
return True
def handle_get(handler, parsed) -> bool:
"""Handle all GET routes. Returns True if handled, False for 404."""
@@ -2520,17 +2548,20 @@ def handle_get(handler, parsed) -> bool:
return _serve_static(handler, stripped)
if parsed.path in ("/", "/index.html") or parsed.path.startswith("/session/"):
from urllib.parse import quote
from api.updates import WEBUI_VERSION
version_token = quote(WEBUI_VERSION, safe="")
from api.extensions import inject_extension_tags
try:
from urllib.parse import quote
from api.updates import WEBUI_VERSION
version_token = quote(WEBUI_VERSION, safe="")
from api.extensions import inject_extension_tags
html = _INDEX_HTML_PATH.read_text(encoding="utf-8").replace("__WEBUI_VERSION__", version_token)
return t(
handler,
inject_extension_tags(html),
content_type="text/html; charset=utf-8",
)
html = _INDEX_HTML_PATH.read_text(encoding="utf-8").replace("__WEBUI_VERSION__", version_token)
return t(
handler,
inject_extension_tags(html),
content_type="text/html; charset=utf-8",
)
except Exception as exc:
return _serve_shell_unavailable(handler, exc)
if parsed.path == "/login":
_settings = load_settings()
Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

+58
View File
@@ -0,0 +1,58 @@
"""Regression coverage for the shell/home route fallback.
The WebUI shell should never render a JSON error page for `/`, even if
index.html serving fails during a restart/update race. API routes still keep
their normal JSON error behavior; this only pins the shell route contract.
"""
from urllib.parse import urlparse
class _FakeHandler:
def __init__(self):
self.status = None
self.sent_headers = []
self.body = bytearray()
self.wfile = self
self.headers = {}
def send_response(self, status):
self.status = status
def send_header(self, name, value):
self.sent_headers.append((name, value))
def end_headers(self):
pass
def write(self, data):
self.body.extend(data)
def header(self, name):
for key, value in self.sent_headers:
if key.lower() == name.lower():
return value
return None
class _BrokenIndexPath:
def read_text(self, *args, **kwargs):
raise RuntimeError("simulated index.html read failure")
def test_home_route_internal_error_returns_html_503_not_json(monkeypatch):
from api import routes
monkeypatch.setattr(routes, "_INDEX_HTML_PATH", _BrokenIndexPath())
handler = _FakeHandler()
assert routes.handle_get(handler, urlparse("http://example.com/")) is True
assert handler.status == 503
assert (handler.header("Content-Type") or "").startswith("text/html; charset=utf-8")
assert handler.header("Cache-Control") == "no-store"
body = bytes(handler.body).decode("utf-8")
assert "Hermes is restarting" in body
assert "application/json" not in (handler.header("Content-Type") or "")
assert '"error"' not in body