Skip to content

Commit b62bd18

Browse files
committed
default html pages for 404 and 500
1 parent 4e23387 commit b62bd18

File tree

2 files changed

+70
-1
lines changed

2 files changed

+70
-1
lines changed

src/air/applications.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,43 @@
2222
from typing_extensions import Annotated, Doc, deprecated
2323
from fastapi import FastAPI
2424
from .responses import TagResponse
25+
from .tags import Html, Head, Body, Main, H1, P, Title
2526

2627

2728
AppType = TypeVar("AppType", bound="FastAPI")
2829

2930

31+
async def default_404_exception_handler(request, exc):
32+
return TagResponse(
33+
Html(
34+
Head(
35+
Title("404 Not Found")),
36+
Body(
37+
Main(
38+
H1("404 Not Found"),
39+
P("The requested resource was not found on this server."),
40+
)
41+
),
42+
),
43+
status_code=404
44+
)
45+
46+
47+
async def default_500_exception_handler(request, exc):
48+
return TagResponse(
49+
Html(
50+
Head(
51+
Title("500 Internal Server Error")),
52+
Body(
53+
Main(
54+
H1("500 Internal Server Error"),
55+
)
56+
),
57+
),
58+
status_code=500
59+
)
60+
61+
3062
class Air(FastAPI):
3163
"""FastAPI wrapper class with TagResponse as the default response class."""
3264

@@ -301,7 +333,7 @@ async def read_items():
301333
# TODO: Have this accept default_response_class=default_response_class
302334
default_response_class=TagResponse,
303335
middleware=middleware,
304-
exception_handlers=exception_handlers,
336+
exception_handlers={404: default_404_exception_handler, 500: default_500_exception_handler},
305337
on_startup=on_startup,
306338
on_shutdown=on_shutdown,
307339
lifespan=lifespan,

tests/test_applications.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from fastapi import FastAPI
22
from fastapi.testclient import TestClient
3+
from fastapi.responses import HTMLResponse
34
import air
45

56

@@ -46,3 +47,39 @@ def test_page():
4647
assert response.status_code == 200
4748
assert response.headers["content-type"] == "text/html; charset=utf-8"
4849
assert response.text == "<h1>Hello, World!</h1>"
50+
51+
52+
def test_air_404_response():
53+
app = air.Air()
54+
55+
client = TestClient(app)
56+
response = client.get("/nonexistent")
57+
58+
assert response.status_code == 404
59+
assert response.headers["content-type"] == "text/html; charset=utf-8"
60+
assert response.text == "<!doctype html><html><head><title>404 Not Found</title></head><body><main><h1>404 Not Found</h1><p>The requested resource was not found on this server.</p></main></body></html>"
61+
62+
63+
64+
def test_air_500_response():
65+
66+
app = air.Air()
67+
68+
@app.get("/error")
69+
def error_endpoint():
70+
raise Exception("This is a test error")
71+
72+
73+
client = TestClient(app)
74+
75+
try:
76+
response = client.get("/error")
77+
except:
78+
79+
80+
81+
82+
assert response.status_code == 500
83+
assert response.headers["content-type"] == "text/html; charset=utf-8"
84+
assert "Internal Server Error" in response.text
85+
assert "This is a test error" in response.text

0 commit comments

Comments
 (0)