Error Handling
This document details the error handling patterns, exception classes, and response shapes for backend applications.
HTTP Status Codes
400 - Bad Request
When to use: Invalid input data that doesn't pass basic validation
raise HTTPException(status_code=400, detail="Invalid input data")
401 - Unauthorized
When to use: Authentication required but not provided or invalid
raise HTTPException(status_code=401, detail="Authentication required")
403 - Forbidden
When to use: Authenticated but lacks permission
raise HTTPException(status_code=403, detail="Access denied")
404 - Not Found
When to use: Requested resource doesn't exist
raise HTTPException(status_code=404, detail="Entity not found")
422 - Validation Error
When to use: Pydantic validation fails (auto-raised by FastAPI)
500 - Internal Server Error
When to use: Unexpected server errors
raise HTTPException(status_code=500, detail="Internal server error")
Custom Exception Classes
EmailAdminHTTPException
Standard Location: utils/exceptions.py
Purpose: HTTP exception that sends email notification to admin when raised
Usage:
from utils.exceptions import EmailAdminHTTPException
raise EmailAdminHTTPException(
status_code=500,
detail="Critical error occurred",
email_admin=True # Triggers admin email notification
)
When to use:
- Critical errors requiring immediate attention
- Unexpected failures that need investigation
- Production issues that impact users
Exception Handlers
Standard Location: exception_handlers.py
The application has global exception handlers:
HTTPException Handler
- Handles all HTTP exceptions
- Checks for
email_adminattribute - Sends admin notification if
email_admin=True - Special handling for 401 with WWW-Authenticate
Generic Exception Handler
- Catches all unhandled exceptions
- Returns 500 status code
- Logs exception details
- Optionally emails admin
Validation Error Handlers
- Handles Pydantic ValidationError
- Handles FastAPI RequestValidationError
- Returns 422 status code
- Formats validation errors for client
Registration in main.py:
from exception_handlers import register_exception_handlers
register_exception_handlers(app)
Error Response Format
All errors return standardized JSON:
{
"success": false,
"title": "An error occurred",
"description": "Detailed error message",
"content": {},
"errorException": "Status 404: Entity not found"
}
Standard Response Models
Defined in database/schemas.py:
class StandardResponse(BaseModel):
success: bool
warning: Optional[bool] = False
title: str
description: str = ""
content: Optional[Dict[str, Any]] = {}
errorException: Optional[str] = ""
class StandardListResponse(BaseModel):
success: bool
warning: Optional[bool] = False
title: str
description: str = ""
content: Optional[List[Any]] = []
errorException: Optional[str] = ""
Layering rule (CRUD vs API)
- CRUD layer: raise exceptions (or return
None) to signal failure; return domain objects/primitives on success. - API layer: converts domain outcomes into HTTP responses and wraps successful payloads in
StandardResponse/StandardListResponse. - Global exception handlers: ensure error responses are consistently shaped even when errors bubble up as
HTTPExceptionor unexpected exceptions.