How to return a custom 404 Not Found page using FastAPI?

Update

A more elegant solution would be to use a custom exception handler, passing the status code of the exception you would like to handle, as shown below:

from fastapi.responses import RedirectResponse
from fastapi.exceptions import HTTPException

@app.exception_handler(404)
async def not_found_exception_handler(request: Request, exc: HTTPException):
    return RedirectResponse('https://fastapi.tiangolo.com')

or, use the exception_handlers parameter of the FastAPI class like this:

async def not_found_error(request: Request, exc: HTTPException):
    return RedirectResponse('https://fastapi.tiangolo.com')

exception_handlers = {404: not_found_error}
app = FastAPI(exception_handlers=exception_handlers)

Note: In the examples above, a RedirectResponse is returned, as OP asked for redirecting the user. However, you could instead return some custom Response, HTMLResponse or Jinja2 TemplateResponse, as demosntrated in the example below.

Working Example

app.py

from fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates
from fastapi.exceptions import HTTPException


async def not_found_error(request: Request, exc: HTTPException):
    return templates.TemplateResponse('404.html', {'request': request}, status_code=404)


async def internal_error(request: Request, exc: HTTPException):
    return templates.TemplateResponse('500.html', {'request': request}, status_code=500)

    
templates = Jinja2Templates(directory='templates')

exception_handlers = {
    404: not_found_error,
    500: internal_error
}

app = FastAPI(exception_handlers=exception_handlers)

templates/404.html

<!DOCTYPE html>
<html>
   <title>Not Found</title>
   <body>
      <h1>Not Found</h1>
      <p>The requested resource was not found on this server.</p>
   </body>
</html>

templates/500.html

<!DOCTYPE html>
<html>
   <title>Internal Server Error</title>
   <body>
      <h1>Internal Server Error</h1>
      <p>The server encountered an internal error or 
         misconfiguration and was unable to complete your request.
      </p>
   </body>
</html>

Original answer

You would need to create a middleware and check for the status_code of the response. If it is 404, then return a RedirectResponse. Example:

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

Leave a Comment