Exception Handling
This module defines the custom exceptions used throughout the auth-middleware library. These exceptions provide specific error handling for authentication and authorization scenarios.
Exception Hierarchy
The auth-middleware library uses a hierarchical exception structure:
AuthMiddlewareException (base)
├── AuthenticationError
├── AuthorizationError
└── ConfigurationError
Exception Types
AuthenticationError
Raised when authentication fails, such as:
Invalid or expired JWT tokens
Missing authentication credentials
Token validation failures
Provider-specific authentication errors
from auth_middleware.exceptions import AuthenticationError
try:
user = await authenticate_user(token)
except AuthenticationError as e:
return JSONResponse(
status_code=401,
content={"error": "Authentication failed", "detail": str(e)}
)
ConfigurationError
Raised when there are configuration issues, such as:
Missing required environment variables
Invalid provider settings
Malformed configuration parameters
from auth_middleware.exceptions import ConfigurationError
try:
provider = create_auth_provider(settings)
except ConfigurationError as e:
logger.error(f"Configuration error: {e}")
raise
Exception Handling Patterns
Middleware Error Handling
The middleware automatically handles exceptions and converts them to appropriate HTTP responses:
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from auth_middleware.exceptions import AuthenticationError, AuthorizationError
app = FastAPI()
@app.exception_handler(AuthenticationError)
async def authentication_error_handler(request: Request, exc: AuthenticationError):
return JSONResponse(
status_code=401,
content={
"error": "authentication_failed",
"message": str(exc),
"type": "AuthenticationError"
}
)
@app.exception_handler(AuthorizationError)
async def authorization_error_handler(request: Request, exc: AuthorizationError):
return JSONResponse(
status_code=403,
content={
"error": "access_denied",
"message": str(exc),
"type": "AuthorizationError"
}
)
Custom Error Responses
You can customize error responses based on the authentication provider:
@app.exception_handler(AuthenticationError)
async def custom_auth_error_handler(request: Request, exc: AuthenticationError):
# Customize response based on provider type
provider_type = getattr(request.state, 'auth_provider_type', 'unknown')
if provider_type == 'cognito':
return JSONResponse(
status_code=401,
content={
"error": "invalid_token",
"error_description": "AWS Cognito authentication failed",
"error_uri": "https://docs.aws.amazon.com/cognito/"
}
)
elif provider_type == 'entra_id':
return JSONResponse(
status_code=401,
content={
"error": "invalid_token",
"error_description": "Azure AD authentication failed",
"error_uri": "https://docs.microsoft.com/azure/active-directory/"
}
)
return JSONResponse(
status_code=401,
content={"error": "authentication_failed", "message": str(exc)}
)
Logging Exceptions
It’s recommended to log exceptions for debugging and monitoring:
import logging
from auth_middleware.exceptions import AuthMiddlewareException
logger = logging.getLogger(__name__)
@app.exception_handler(AuthMiddlewareException)
async def log_auth_errors(request: Request, exc: AuthMiddlewareException):
logger.warning(
f"Auth error: {exc.__class__.__name__}: {exc}",
extra={
"path": request.url.path,
"method": request.method,
"client": request.client.host if request.client else None,
"user_agent": request.headers.get("user-agent"),
}
)
# Re-raise to let other handlers process it
raise exc