Search code examples
python-3.xexceptionfastapi

Catch `Exception` globally in FastAPI


I am trying to catch unhandled exceptions at global level. So somewhere in main.py file I have the below:

@app.exception_handler(Exception)
async def exception_callback(request: Request, exc: Exception):
  logger.error(exc.detail)

But the above method is never executed. However, if I write a custom exception and try to catch it (as shown below), it works just fine.

class MyException(Exception):
  #some code

@app.exception_handler(MyException)
async def exception_callback(request: Request, exc: MyException):
  logger.error(exc.detail)

I have gone through Catch exception type of Exception and process body request #575. But this bug talks about accessing request body. After seeing this bug, I feel it should be possible to catch Exception. FastAPI version I am using is: fastapi>=0.52.0.

Thanks in advance :)


Update

There are multiple answers, I am thankful to all the readers and authors here. I was revisiting this solution in my application. Now I see that I needed to set debug=False, default it's False, but I had it set to True in

server = FastAPI(
    title=app_settings.PROJECT_NAME,
    version=app_settings.VERSION,
)

It seems that I missed it when @iedmrc commented on answer given by @Kavindu Dodanduwa.


Solution

  • In case you want to capture all unhandled exceptions (internal server error), there's a very simple way of doing it. Documentation

    from fastapi import FastAPI
    from starlette.requests import Request
    from starlette.responses import Response
    from traceback import print_exception
    
    app = FastAPI()
    
    async def catch_exceptions_middleware(request: Request, call_next):
        try:
            return await call_next(request)
        except Exception:
            # you probably want some kind of logging here
            print_exception(e)
            return Response("Internal server error", status_code=500)
    
    app.middleware('http')(catch_exceptions_middleware)
    

    Make sure you place this middleware before everything else.