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
API Reference
Auth-middleware exceptions.
- exception auth_middleware.exceptions.AuthenticationError(detail: str = 'Invalid credentials')[source]
Bases:
HTTPExceptionRaised when credentials are invalid or the session has expired.
- exception auth_middleware.exceptions.ChallengeRequiredError(challenge_name: str, session: str)[source]
Bases:
ExceptionInternal signal: Cognito returned a challenge instead of tokens.
Not raised directly to the HTTP layer — caught by the service and converted to a ChallengeResponse.
- exception auth_middleware.exceptions.InvalidAuthorizationException(status_code: Annotated[int, Doc('\n HTTP status code to send to the client.\n ')], detail: Annotated[Any, Doc('\n Any data to be sent to the client in the `detail` key of the JSON\n response.\n ')] = None, headers: Annotated[dict[str, str] | None, Doc('\n Any headers to send to the client in the response.\n ')] = None)[source]
Bases:
HTTPExceptionException thrown when the authorization header is invalid
- Parameters:
HTTPException (_type_) – _description_
- exception auth_middleware.exceptions.InvalidChallengeError(detail: str = 'Invalid or expired challenge')[source]
Bases:
HTTPExceptionRaised when the challenge response is incorrect or the session is expired.
- exception auth_middleware.exceptions.InvalidCredentialsException(status_code: Annotated[int, Doc('\n HTTP status code to send to the client.\n ')], detail: Annotated[Any, Doc('\n Any data to be sent to the client in the `detail` key of the JSON\n response.\n ')] = None, headers: Annotated[dict[str, str] | None, Doc('\n Any headers to send to the client in the response.\n ')] = None)[source]
Bases:
HTTPExceptionException thrown when the user credentials are invalid
- Parameters:
HTTPException (_type_) – _description_
- exception auth_middleware.exceptions.InvalidTokenException(status_code: Annotated[int, Doc('\n HTTP status code to send to the client.\n ')], detail: Annotated[Any, Doc('\n Any data to be sent to the client in the `detail` key of the JSON\n response.\n ')] = None, headers: Annotated[dict[str, str] | None, Doc('\n Any headers to send to the client in the response.\n ')] = None)[source]
Bases:
HTTPExceptionException thrown when the token is invalid
- Parameters:
HTTPException (_type_) – _description_
- exception auth_middleware.exceptions.MfaSetupError(detail: str = 'MFA setup failed')[source]
Bases:
HTTPExceptionRaised when a TOTP setup or verification operation fails.
- exception auth_middleware.exceptions.PasswordPolicyError(detail: str = 'Password does not meet policy requirements')[source]
Bases:
HTTPExceptionRaised when the new password does not meet Cognito’s password policy.