I'm trying to override the default exception handler in a FastAPI application so I can log any exceptions that happen. The problem that I run into is that my handler seems to run as it logs what I want but I'm getting a 500 back to the client because of an error in the built-it ServerErrorMiddleware: Traceback (most recent call last): File "c:\users\jtaft\appdata\local\programs\python\python38\lib\site-packages\hypercorn\asyncio\task_group.py", line 27, in _handle await app(scope, receive, send, sync_spawn, call_soon) File "c:\users\jtaft\appdata\local\programs\python\python38\lib\site-packages\hypercorn\app_wrappers.py", line 34, in __call__ await self.app(scope, receive, send) File "c:\users\jtaft\appdata\local\programs\python\python38\lib\site-packages\fastapi\applications.py", line 1054, in __call__ await super().__call__(scope, receive, send) File "c:\users\jtaft\appdata\local\programs\python\python38\lib\site-packages\starlette\applications.py", line 112, in __call__ await self.middleware_stack(scope, receive, send) File "c:\users\jtaft\appdata\local\programs\python\python38\lib\site-packages\starlette\middleware\errors.py", line 189, in __call__ await response(scope, receive, send) TypeError: 'NoneType' object is not callable This is my handler: async def default_exception_handler(request: Request, exc: Exception, logger:logging.Logger) -> JSONResponse: tempPath: str = request['path'] tempScriptPathList: List[str] = sys.argv[0].split("\\") # The [0] is neded to get the value, slicing the list, still returns a list. if tempScriptPathList[-1:][0] in ['hypercorn']: tempScriptPath = sys.argv[1] else: tempScriptPath = sys.argv[0] for pp in request.path_params: if request.path_params[pp] in tempPath: tempPath = tempPath.replace(request.path_params[pp], f"{{{pp}}}") tempLogDict = {"message": exc.args[0], "api_request_id": str(uuid.uuid4()), "method": request.method, "client_ip": request.client.host, "log_type": "alert", "path": tempPath, "script": tempScriptPath, "query_params": request.query_params._dict, "path_params": request.path_params, "error":{ "error_code": 500, "error_message": exc.args[0], "stack_trace": traceback.format_exc().splitlines() } } logger.error(f'{json.dumps(tempLogDict)}') return JSONResponse(status_code=HTTP_500_INTERNAL_SERVER_ERROR, content=jsonable_encoder({"detail":tempLogDict['message']}), headers={'x-api-request-id':tempLogDict['api_request_id']}) The logger.error line works because it will write to the logger, but I'm not getting the JSONresponse back. I've change the status code to see if I was getting the code but not the content or the headers but that didn't change that I'm getting the generic 500 from ServerErrorMiddleware. Best I can tell, my handler runs but doesn't return what ServerErrorMiddleware expects and that causes the general 500, but I cant figure out why. This is how I'm adding my handler: @app.exception_handler(Exception) async def exception_callback(request: Request, exc: Exception): await default_exception_handler(request, exc, ql.logger) Starlette: 0.44.0 FastAPI: 0.115.12 Continue reading...