I am writing an app using the python fastapi
library. Parts of my code raise different exceptions which I need to process. I want all that processing to be done in a single place (with different except blocks depending on what exception was raised). I tried to do this by adding the following (simplified) middleware to my FastAPI app:
from fastapi import APIRouter, FastAPI, Request, HTTPException, Response, status
from starlette.middleware.base import BaseHTTPMiddleware
from fastapi.responses import JSONResponse
class ExceptionHandlerMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
try:
return await call_next(request)
except HTTPException as e:
return JSONResponse(status_code=e.status_code, content={'message': e.detail})
except Exception as e:
return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={'message': str(e)})
# app creation and config go here....
app.add_middleware(ExceptionHandlerMiddleware)
The problem is that this does not work for some specific exceptions which fastapi handles by default (for example if a HTTPException
is raised, it will never reach the except block in my middleware because it will already be processed by default before reaching the middleware)
Fastapi documentation gives a way to override default behavior for specific exceptions, but this is tedious and not scalable. Is there a way to globally force all exception handling to go through my middleware? (bonus points if anyone knows a way to do this without using decorators, as one requirement I have is to not use them)
UPDATE: My question was initially closed as a duplicate of this question, however it is NOT the same thing. That question deals with catching unhandled exceptions, and in my question I am dealing with forcing the handling of exceptions that are handled by default (like HTTPException
) to happen elsewhere in code that I control (as stated in my question, attempting to catch HTTPException
in the middleware does not work! (which would be the takeaway from the linked question))
app.exception_handlers = {}
. This should in theory force all errors (be itHTTPException
or anything else) to go through my middleware, but this is not the case (maybe. a fastapi bug?). I do not want to specify per-exception-type error handling as your and the other answers state, but want to disable the fastapi default behavior completely, and force all exception handling to go to one place (my middleware) – Clinkerbuilt