Custom error response models help you send clear and consistent error messages from your API. This makes it easier for users and developers to understand what went wrong.
Custom error response models in FastAPI
Start learning this pattern below
Jump into concepts and practice - no test required
or
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction
Syntax
FastAPI
from fastapi import FastAPI, HTTPException, Request from fastapi.responses import JSONResponse from pydantic import BaseModel class ErrorResponse(BaseModel): detail: str app = FastAPI() @app.exception_handler(HTTPException) async def custom_http_exception_handler(request: Request, exc: HTTPException): return JSONResponse( status_code=exc.status_code, content=ErrorResponse(detail=exc.detail).dict() )
Define a Pydantic model to describe the error response structure.
Use FastAPI's exception handler decorator to customize error responses.
Examples
FastAPI
class ErrorResponse(BaseModel): detail: str
FastAPI
@app.exception_handler(HTTPException) async def custom_http_exception_handler(request: Request, exc: HTTPException): return JSONResponse( status_code=exc.status_code, content=ErrorResponse(detail=exc.detail).dict() )
FastAPI
@app.get('/items/{item_id}') async def read_item(item_id: int): if item_id < 1: raise HTTPException(status_code=400, detail='Item ID must be positive') return {'item_id': item_id}
Sample Program
This FastAPI app defines a custom error response model. When you request an item with an invalid ID (less than 1), it returns a clear error message using the custom model.
FastAPI
from fastapi import FastAPI, HTTPException, Request from fastapi.responses import JSONResponse from pydantic import BaseModel class ErrorResponse(BaseModel): detail: str app = FastAPI() @app.exception_handler(HTTPException) async def custom_http_exception_handler(request: Request, exc: HTTPException): return JSONResponse( status_code=exc.status_code, content=ErrorResponse(detail=exc.detail).dict() ) @app.get('/items/{item_id}') async def read_item(item_id: int): if item_id < 1: raise HTTPException(status_code=400, detail='Item ID must be positive') return {'item_id': item_id}
Important Notes
Custom error models improve API clarity and help clients handle errors better.
Always keep error messages simple and informative.
Summary
Custom error response models let you control how errors look in your API.
Use Pydantic models to define error message structure.
Handle exceptions with FastAPI's exception handlers to return these models.
Practice
1. What is the main purpose of using custom error response models in FastAPI?
easy
Solution
Step 1: Understand error response models
Custom error response models define how error messages look, making them clear and consistent.Step 2: Identify the purpose in FastAPI
FastAPI uses these models to send structured error info to clients, improving API usability.Final Answer:
To define a clear and consistent structure for error messages returned by the API -> Option AQuick Check:
Custom error models = clear error messages [OK]
Hint: Custom error models shape error messages clearly [OK]
Common Mistakes:
- Thinking they speed up API responses
- Believing they fix code errors automatically
- Assuming they hide errors completely
2. Which of the following is the correct way to define a custom error response model using Pydantic in FastAPI?
easy
Solution
Step 1: Recognize Pydantic model syntax
Pydantic models are defined as classes inheriting from BaseModel with typed attributes.Step 2: Match correct syntax
class ErrorResponse(BaseModel): message: str; code: int correctly defines a class with typed fields using BaseModel.Final Answer:
class ErrorResponse(BaseModel): message: str; code: int -> Option BQuick Check:
Pydantic model = class with BaseModel [OK]
Hint: Use class with BaseModel and typed fields [OK]
Common Mistakes:
- Defining models as functions
- Using plain dictionaries instead of classes
- Missing BaseModel inheritance
3. Given this FastAPI code snippet, what will be the response when a
ValueError is raised?
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from pydantic import BaseModel
app = FastAPI()
class ErrorResponse(BaseModel):
detail: str
@app.exception_handler(ValueError)
async def value_error_handler(request: Request, exc: ValueError):
return JSONResponse(
status_code=400,
content=ErrorResponse(detail=str(exc)).dict()
)
@app.get("/test")
async def test():
raise ValueError("Invalid input")medium
Solution
Step 1: Understand exception handler behavior
The handler catches ValueError and returns JSONResponse with ErrorResponse model content and status 400.Step 2: Check response content and status
The content is the dict form of ErrorResponse with detail set to the exception message, so JSON has key 'detail' with 'Invalid input'.Final Answer:
{"detail": "Invalid input"} with status 400 -> Option CQuick Check:
Exception handler returns JSON with detail key [OK]
Hint: Exception handler returns model dict as JSON with status [OK]
Common Mistakes:
- Expecting plain text instead of JSON
- Confusing status codes
- Assuming different JSON key names
4. Identify the error in this FastAPI custom error handler code:
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from pydantic import BaseModel
app = FastAPI()
class ErrorResponse(BaseModel):
message: str
@app.exception_handler(KeyError)
async def key_error_handler(request: Request, exc: KeyError):
return JSONResponse(
status_code=404,
content=ErrorResponse(message=exc).dict()
)medium
Solution
Step 1: Check how exception is passed to model
The code passes exc (KeyError object) directly to message field which expects a string.Step 2: Identify correct usage
It should convert exc to string with str(exc) to avoid type errors.Final Answer:
Passing the exception object directly instead of converting to string -> Option DQuick Check:
Exception message must be string [OK]
Hint: Convert exception to string before passing to model [OK]
Common Mistakes:
- Passing exception object without str()
- Confusing async/sync handler rules
- Incorrect status code choice
5. You want to create a FastAPI app that returns a custom error response with fields
error_code (int) and error_msg (str) whenever a RuntimeError occurs. Which of the following code snippets correctly implements this behavior?hard
Solution
Step 1: Define correct Pydantic model
class CustomError(BaseModel): error_code: int; error_msg: str @app.exception_handler(RuntimeError) async def runtime_error_handler(request: Request, exc: RuntimeError): return JSONResponse(status_code=500, content=CustomError(error_code=1001, error_msg=str(exc)).dict()) defines CustomError inheriting from BaseModel with correct field types (int and str).Step 2: Implement exception handler properly
class CustomError(BaseModel): error_code: int; error_msg: str @app.exception_handler(RuntimeError) async def runtime_error_handler(request: Request, exc: RuntimeError): return JSONResponse(status_code=500, content=CustomError(error_code=1001, error_msg=str(exc)).dict())'s handler returns JSONResponse with status 500 and content as dict from CustomError instance, converting exception to string.Step 3: Check other options for errors
class CustomError(BaseModel): error_code: str; error_msg: int @app.exception_handler(RuntimeError) async def runtime_error_handler(request: Request, exc: RuntimeError): return JSONResponse(status_code=400, content=CustomError(error_code='1001', error_msg=exc).dict()) swaps types incorrectly and passes exc without str(); class CustomError: def __init__(self, error_code, error_msg): self.error_code = error_code self.error_msg = error_msg @app.exception_handler(RuntimeError) async def runtime_error_handler(request: Request, exc: RuntimeError): return JSONResponse(status_code=500, content=CustomError(1001, str(exc))) uses plain class not BaseModel and returns object not dict; @app.exception_handler(RuntimeError) async def runtime_error_handler(request: Request, exc: RuntimeError): return JSONResponse(status_code=500, content={'error_code': 1001, 'error_msg': str(exc)}) skips model usage.Final Answer:
Option A correctly defines model and handler returning proper JSON response -> Option AQuick Check:
Use BaseModel with typed fields and dict() in handler [OK]
Hint: Use BaseModel and dict() for error response content [OK]
Common Mistakes:
- Swapping field types in model
- Not converting exception to string
- Returning model instance instead of dict
- Skipping Pydantic model for error response
