Exceptions

Exceptions#

In backend development, there are situations where you need to return messages to the user indicating errors during code execution. There are dedicated objects designed for this purpose: HTTPException, RequestValidationError, StarletteHTTPException, and so on. You can even create your custom exceptions. The key feature of these objects is that you must raise them, not return them.

Find out more in handling errors official fastAPI documentation.

import requests

!docker run --rm -itd\
    --name test_container\
    -v ./exceptions_files/app.py:/app.py\
    -p 8000:8000 \
    fastapi_experiment \
    uvicorn --host 0.0.0.0 --reload app:app
7122b07d3d06130565a3a4ae8bf0ced9da081e4a2d866130556f2374df79db5f

Note don’t forget to stop container after all your tests.

!docker stop test_container
test_container

HTTPException#

The most common way to define exceptions in FastAPI.


The following cell defines an application that returns an HTTPException for each call, with a specified status code, content, and headers.

%%writefile exceptions_files/app.py
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from fastapi.exceptions import HTTPException

app = FastAPI()

@app.get("/")
def index():
    raise HTTPException(
        status_code=400, 
        detail="Test value",
        headers={"key": "value"}
    )
Overwriting exceptions_files/app.py

Now let’s check what we got back.

response = requests.get("http://localhost:8000")
print(response.status_code)
print(response.content)
print(response.headers)
400
b'{"detail":"Test value"}'
{'date': 'Wed, 21 Aug 2024 14:35:30 GMT', 'server': 'uvicorn', 'key': 'value', 'content-length': '23', 'content-type': 'application/json'}

All parameters influence the response in the typical FastAPI manner.

Custom#

You can create a custom exception by defining a class that inherits from Exception. Then, use the app.exception_handler decorator to associate this exception class with a specific function.


The following example demonstrates how to handle a custom exception. The class MyException inherits from Exception, and instances of this class can be raised as exceptions. The unicorn_exception_handler function is decorated with app.exception_handler(MyException), ensuring that it is invoked whenever a MyException is raised.

%%writefile exceptions_files/app.py
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse

class MyException(Exception):
    def __init__(self, message):
        self.message = message

app = FastAPI()

@app.exception_handler(MyException)
def unicorn_exception_handler(request: Request, exc: MyException):
    return JSONResponse(
        status_code=418,
        content={"message": f"Oops! {exc.message} did something."},
        headers={"key1": "10", "key2": "string value"}
    )

@app.get("/")
def divide():
    raise MyException("My god")
Overwriting exceptions_files/app.py

Now, let’s test the newly created API with a request.

response = requests.get("http://localhost:8000")

print("status_code", response.status_code)
print("content", response.content)
print("headers", response.headers)
status_code 418
content b'{"message":"Oops! My god did something."}'
headers {'date': 'Thu, 22 Aug 2024 07:37:41 GMT', 'server': 'uvicorn', 'key1': '10', 'key2': 'string value', 'content-length': '41', 'content-type': 'application/json'}

We received a typical FastAPI error message, but it was customized according to the specified behavior.