Add custom 404 error page

This commit is contained in:
Louis King
2026-01-26 22:01:00 +00:00
parent c42b26c8f3
commit fd582bda35
2 changed files with 55 additions and 0 deletions

View File

@@ -7,8 +7,10 @@ from typing import AsyncGenerator
import httpx
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from starlette.exceptions import HTTPException as StarletteHTTPException
from meshcore_hub import __version__
from meshcore_hub.common.schemas import RadioConfig
@@ -150,6 +152,24 @@ def create_app(
except Exception as e:
return {"status": "not_ready", "api": str(e)}
@app.exception_handler(StarletteHTTPException)
async def http_exception_handler(
request: Request, exc: StarletteHTTPException
) -> HTMLResponse:
"""Handle HTTP exceptions with custom error pages."""
if exc.status_code == 404:
context = get_network_context(request)
context["request"] = request
context["detail"] = exc.detail if exc.detail != "Not Found" else None
return templates.TemplateResponse(
"errors/404.html", context, status_code=404
)
# For other errors, return a simple response
return HTMLResponse(
content=f"<h1>{exc.status_code}</h1><p>{exc.detail}</p>",
status_code=exc.status_code,
)
return app

View File

@@ -0,0 +1,35 @@
{% extends "base.html" %}
{% block title %}Page Not Found - {{ network_name }}{% endblock %}
{% block content %}
<div class="hero min-h-[60vh]">
<div class="hero-content text-center">
<div class="max-w-md">
<div class="text-9xl font-bold text-primary opacity-20">404</div>
<h1 class="text-4xl font-bold -mt-8">Page Not Found</h1>
<p class="py-6 text-base-content/70">
{% if detail %}
{{ detail }}
{% else %}
The page you're looking for doesn't exist or has been moved.
{% endif %}
</p>
<div class="flex gap-4 justify-center">
<a href="/" class="btn btn-primary">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
</svg>
Go Home
</a>
<a href="/nodes" class="btn btn-outline">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
</svg>
Browse Nodes
</a>
</div>
</div>
</div>
</div>
{% endblock %}