如何制作自定义404页面?
How to make a custom 404 page?
我正在为 Discord 创建一个 rick roll 网站,我想在 404
响应状态代码上重定向到 rick roll 页面。
我试过以下方法,但没有用:
@app.exception_handler(fastapi.HTTPException)
async def http_exception_handler(request, exc):
...
您需要创建一个 middleware
and check for the status_code
of the response
. If it is 404
, then return a RedirectResponse
。示例:
from fastapi import Request
from fastapi.responses import RedirectResponse
@app.middleware("http")
async def redirect_on_not_found(request: Request, call_next):
response = await call_next(request)
if response.status_code == 404:
return RedirectResponse("https://fastapi.tiangolo.com")
else:
return response
from fastapi import FastAPI
from fastapi.templating import Jinja2Templates
from starlette.exceptions import HTTPException
# --- Constants --- #
templates = Jinja2Templates(directory="./templates")
# --- Error handler --- #
def lost_page(request, exception):
headers = {"Content-Type": "text/html"}
if isinstance(exception, HTTPException):
status_code = exception.status_code
detail = exception.detail
elif isinstance(exception, Exception):
status_code = 500
detail = "Server Error"
headers["X-Error-Message"] = exception.__class__.__name__
headers["X-Error-Line"] = str(exception.__traceback__.tb_lineno)
else:
status_code = 500
detail = f"Server Error\n\nDetails: {exception}"
return templates.TemplateResponse(
"404.html",
{"request": request, "status_code": status_code, "detail": detail},
status_code=status_code,
headers=headers,
)
exception_handlers = {num: lost_page for num in range(400, 599)}
app = FastAPI(exception_handlers=exception_handlers)
这是我在几个项目中使用的一个片段,它本质上是一个 catch-all 用于所有 400 和 500 状态代码。
from fastapi import FastAPI
from fastapi.templating import Jinja2Templates
from starlette.exceptions import HTTPException
# --- Constants --- #
templates = Jinja2Templates(directory="./templates")
此块导入相关库并初始化 Jinja2Templates,这允许我们使用 FastAPI 渲染 HTML。 Docs.
来剖析一下
def lost_page(request, exception):
headers = {"Content-Type": "text/html"}
if isinstance(exception, HTTPException):
status_code = exception.status_code
detail = exception.detail
elif isinstance(exception, Exception):
status_code = 500
detail = "Server Error"
headers["X-Error-Message"] = exception.__class__.__name__
headers["X-Error-Line"] = str(exception.__traceback__.tb_lineno)
else:
status_code = 500
detail = f"Server Error\n\nDetails: {exception}"
return templates.TemplateResponse(
"404.html",
{"request": request, "status_code": status_code, "detail": detail},
status_code=status_code,
headers=headers,
)
FastAPI 的异常处理程序提供两个参数,导致异常的请求 object 和引发的异常。
def lost_page(request, exception):
^^ 我们的函数接受这两个参数。
headers = {"Content-Type": "text/html"}
这些是我们将随请求一起发回的 headers。
if isinstance(exception, HTTPException):
status_code = exception.status_code
detail = exception.detail
elif isinstance(exception, Exception):
status_code = 500
detail = "Server Error"
headers["X-Error-Name"] = exception.__class__.__name__
else:
status_code = 500
detail = f"Server Error\n\nDetails: {exception}"
如果 exception
参数是 HTTPException(由 Starlette/FastAPI 引发),那么我们将适当地设置 status_code 和详细信息。 HTTPException 的一个示例是 404 错误,如果您尝试访问不存在的端点,则会引发 HTTPException 并由 FastAPI 自动处理。
然后,我们检查它是否是 Exception
的实例,它是 Python 的 in-built 异常 classes 之一。这涵盖了 ZeroDivisionError
、FileNotFoundError
等异常。这通常意味着这是我们代码的问题,例如试图打开一个不存在的文件、除以零、使用未知数属性,或引发未在端点函数内部处理的异常的其他内容。
else
块无论如何都不应该触发的,可以去掉,只是为了安抚自己的良心。
设置status_code
、detail
、headers后,
return templates.TemplateResponse(
"404.html",
{"request": request, "status_code": status_code, "detail": detail},
status_code=status_code,
headers=headers,
)
我们 return 我们的 404 模板,TemplateResponse 函数接受一些参数,"404.html"
是我们想要 return 的文件,{"request": request, "status_code": status_code, "detail": detail}
是请求 object 和我们要填充的嵌入值(嵌入是在 jinja2 和 Python 之间传递信息的一种方式)。然后我们定义响应的状态代码,以及它的 headers.
This 是我与错误处理程序一起使用的 404 html 模板。
exception_handlers = {num: lost_page for num in range(400, 599)}
app = FastAPI(exception_handlers=exception_handlers)
异常处理程序使用字典理解来创建状态代码字典,以及应该调用的函数,
exception_handlers = {400: lost_page, 401: lost_page, 402: lost_page, ...}
就是这样理解之后的样子,直到599。
FastAPI 允许我们将此字典作为 FastAPI
class,
的参数传递
app = FastAPI(exception_handlers=exception_handlers)
这告诉 FastAPI 在端点函数 return 是特定状态代码时 运行 以下函数。
总而言之,上面的代码片段和 this 错误模板应该可以帮助您以一种漂亮、user-friendly 和干净的方式处理所有 FastAPI 错误。
我正在为 Discord 创建一个 rick roll 网站,我想在 404
响应状态代码上重定向到 rick roll 页面。
我试过以下方法,但没有用:
@app.exception_handler(fastapi.HTTPException)
async def http_exception_handler(request, exc):
...
您需要创建一个 middleware
and check for the status_code
of the response
. If it is 404
, then return a RedirectResponse
。示例:
from fastapi import Request
from fastapi.responses import RedirectResponse
@app.middleware("http")
async def redirect_on_not_found(request: Request, call_next):
response = await call_next(request)
if response.status_code == 404:
return RedirectResponse("https://fastapi.tiangolo.com")
else:
return response
from fastapi import FastAPI
from fastapi.templating import Jinja2Templates
from starlette.exceptions import HTTPException
# --- Constants --- #
templates = Jinja2Templates(directory="./templates")
# --- Error handler --- #
def lost_page(request, exception):
headers = {"Content-Type": "text/html"}
if isinstance(exception, HTTPException):
status_code = exception.status_code
detail = exception.detail
elif isinstance(exception, Exception):
status_code = 500
detail = "Server Error"
headers["X-Error-Message"] = exception.__class__.__name__
headers["X-Error-Line"] = str(exception.__traceback__.tb_lineno)
else:
status_code = 500
detail = f"Server Error\n\nDetails: {exception}"
return templates.TemplateResponse(
"404.html",
{"request": request, "status_code": status_code, "detail": detail},
status_code=status_code,
headers=headers,
)
exception_handlers = {num: lost_page for num in range(400, 599)}
app = FastAPI(exception_handlers=exception_handlers)
这是我在几个项目中使用的一个片段,它本质上是一个 catch-all 用于所有 400 和 500 状态代码。
from fastapi import FastAPI
from fastapi.templating import Jinja2Templates
from starlette.exceptions import HTTPException
# --- Constants --- #
templates = Jinja2Templates(directory="./templates")
此块导入相关库并初始化 Jinja2Templates,这允许我们使用 FastAPI 渲染 HTML。 Docs.
来剖析一下
def lost_page(request, exception):
headers = {"Content-Type": "text/html"}
if isinstance(exception, HTTPException):
status_code = exception.status_code
detail = exception.detail
elif isinstance(exception, Exception):
status_code = 500
detail = "Server Error"
headers["X-Error-Message"] = exception.__class__.__name__
headers["X-Error-Line"] = str(exception.__traceback__.tb_lineno)
else:
status_code = 500
detail = f"Server Error\n\nDetails: {exception}"
return templates.TemplateResponse(
"404.html",
{"request": request, "status_code": status_code, "detail": detail},
status_code=status_code,
headers=headers,
)
FastAPI 的异常处理程序提供两个参数,导致异常的请求 object 和引发的异常。
def lost_page(request, exception):
^^ 我们的函数接受这两个参数。
headers = {"Content-Type": "text/html"}
这些是我们将随请求一起发回的 headers。
if isinstance(exception, HTTPException):
status_code = exception.status_code
detail = exception.detail
elif isinstance(exception, Exception):
status_code = 500
detail = "Server Error"
headers["X-Error-Name"] = exception.__class__.__name__
else:
status_code = 500
detail = f"Server Error\n\nDetails: {exception}"
如果 exception
参数是 HTTPException(由 Starlette/FastAPI 引发),那么我们将适当地设置 status_code 和详细信息。 HTTPException 的一个示例是 404 错误,如果您尝试访问不存在的端点,则会引发 HTTPException 并由 FastAPI 自动处理。
然后,我们检查它是否是 Exception
的实例,它是 Python 的 in-built 异常 classes 之一。这涵盖了 ZeroDivisionError
、FileNotFoundError
等异常。这通常意味着这是我们代码的问题,例如试图打开一个不存在的文件、除以零、使用未知数属性,或引发未在端点函数内部处理的异常的其他内容。
else
块无论如何都不应该触发的,可以去掉,只是为了安抚自己的良心。
设置status_code
、detail
、headers后,
return templates.TemplateResponse(
"404.html",
{"request": request, "status_code": status_code, "detail": detail},
status_code=status_code,
headers=headers,
)
我们 return 我们的 404 模板,TemplateResponse 函数接受一些参数,"404.html"
是我们想要 return 的文件,{"request": request, "status_code": status_code, "detail": detail}
是请求 object 和我们要填充的嵌入值(嵌入是在 jinja2 和 Python 之间传递信息的一种方式)。然后我们定义响应的状态代码,以及它的 headers.
This 是我与错误处理程序一起使用的 404 html 模板。
exception_handlers = {num: lost_page for num in range(400, 599)}
app = FastAPI(exception_handlers=exception_handlers)
异常处理程序使用字典理解来创建状态代码字典,以及应该调用的函数,
exception_handlers = {400: lost_page, 401: lost_page, 402: lost_page, ...}
就是这样理解之后的样子,直到599。
FastAPI 允许我们将此字典作为 FastAPI
class,
app = FastAPI(exception_handlers=exception_handlers)
这告诉 FastAPI 在端点函数 return 是特定状态代码时 运行 以下函数。
总而言之,上面的代码片段和 this 错误模板应该可以帮助您以一种漂亮、user-friendly 和干净的方式处理所有 FastAPI 错误。