In FastAPI, errors can occur at different stages of the request - response cycle. These errors can be due to various reasons such as invalid input data, database issues, or internal server errors. FastAPI provides a way to catch these errors and return appropriate HTTP responses to the client.
The main types of errors in FastAPI include:
HTTPException
HTTPException
is a built - in exception class in FastAPI that allows you to raise HTTP errors easily. You can specify the HTTP status code and an optional detail message.
from fastapi import FastAPI, HTTPException
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: int):
if item_id < 0:
raise HTTPException(status_code=400, detail="Item ID cannot be negative")
return {"item_id": item_id}
In this example, if the item_id
is negative, a 400 Bad Request
error is raised with a custom detail message.
FastAPI allows you to define custom exception handlers to handle specific types of exceptions. You can use the @app.exception_handler
decorator to register a function that will be called when a specific exception is raised.
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
app = FastAPI()
class CustomException(Exception):
def __init__(self, message: str):
self.message = message
@app.exception_handler(CustomException)
async def custom_exception_handler(request: Request, exc: CustomException):
return JSONResponse(
status_code=418,
content={"message": f"Oops! {exc.message}"}
)
@app.get("/trigger_custom_exception")
async def trigger_custom_exception():
raise CustomException("This is a custom exception.")
In this example, we define a custom exception CustomException
and a custom exception handler for it. When the /trigger_custom_exception
endpoint is called, the custom exception is raised, and the custom exception handler returns a 418 I'm a Teapot
response with a custom message.
It is important to log errors for debugging and monitoring purposes. You can use Python’s built - in logging
module to log errors.
import logging
from fastapi import FastAPI, HTTPException
app = FastAPI()
logging.basicConfig(level=logging.ERROR)
@app.get("/error_logging_example")
async def error_logging_example():
try:
result = 1 / 0
return {"result": result}
except ZeroDivisionError as e:
logging.error(f"ZeroDivisionError: {e}")
raise HTTPException(status_code=500, detail="Internal server error")
In this example, if a ZeroDivisionError
occurs, the error is logged, and a 500 Internal Server Error
is returned to the client.
To make it easier for clients to handle errors, it is a good practice to return consistent error responses. You can define a standard error response structure.
from fastapi import FastAPI, HTTPException
app = FastAPI()
def standard_error_response(status_code: int, message: str):
return {
"status": "error",
"status_code": status_code,
"message": message
}
@app.get("/consistent_error_example")
async def consistent_error_example():
try:
result = 1 / 0
return {"result": result}
except ZeroDivisionError:
error = standard_error_response(500, "Internal server error")
raise HTTPException(status_code=500, detail=error)
Instead of handling errors in individual endpoints, it is better to have a centralized error handling mechanism. You can create a module or a set of functions to handle all types of errors.
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
import logging
app = FastAPI()
logging.basicConfig(level=logging.ERROR)
def handle_general_error(request: Request, exc: Exception):
logging.error(f"Error: {exc}")
return JSONResponse(
status_code=500,
content={"status": "error", "status_code": 500, "message": "Internal server error"}
)
app.add_exception_handler(Exception, handle_general_error)
You should write tests for your error handling code to ensure that it works as expected. You can use the TestClient
from fastapi.testclient
to test your endpoints.
from fastapi.testclient import TestClient
from main import app
client = TestClient(app)
def test_error_logging_example():
response = client.get("/error_logging_example")
assert response.status_code == 500
assert response.json()["detail"] == "Internal server error"
Error handling is an essential part of building robust and reliable FastAPI applications. By using the built - in HTTPException
class, custom exception handlers, and following common and best practices such as error logging, returning consistent error responses, centralized error handling, and testing error handling, you can ensure that your application gracefully handles errors and provides a better user experience.