Skip to content

Overwriting HTTPException and RequestValidationError does not work via FastAPI exceptions handlers init #1440

@timbmg

Description

@timbmg

When initilizing FastAPI, an exception_handlers dictionary can be passed, mapping Exceptions/Error Codes to callables. When using this method to set the exception handlers, the HTTPException and RequestValidationError can not be overwritten.

Code to Reproducte

import logging

import uvicorn
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from fastapi.exception_handlers import request_validation_exception_handler


logger = logging.getLogger(__name__)

# app = FastAPI()
# @app.exception_handler(RequestValidationError)
async def my_request_validation_exception_handler(
    req: Request, exc: RequestValidationError
):
    logger.info("my_request_validation_exception_handler")
    return await request_validation_exception_handler(req, exc)

app = FastAPI(exception_handlers={RequestValidationError: my_request_validation_exception_handler})

@app.get("/test")
def test(param: int):

    return JSONResponse(
        status_code=200,
        content={"message": "successful test with param {}".format(param)},
    )


if __name__ == "__main__":
    uvicorn.run("api:app", host="localhost", port=2000, reload=True)

Now a curl "http://localhost:2000/test" will not show the logger.info("my_request_validation_exception_handler") log statement. However, when using the commented out code it works fine. I want to use the other way to keep the handlers in a separate file.

Environment

  • OS: Windows/WSL
  • FastAPI Version: 0.54.2
  • Python version: 3.6.9

Origin

As far as i can see this is coming from the setup method

self.add_exception_handler(HTTPException, http_exception_handler)
self.add_exception_handler(
    RequestValidationError, request_validation_exception_handler
)

Starlette will overwrite the custom handlers in the add_exception_handler method

def add_exception_handler(
        self,
        exc_class_or_status_code: typing.Union[int, typing.Type[Exception]],
        handler: typing.Callable,
    ) -> None:
        self.exception_handlers[exc_class_or_status_code] = handler
        self.middleware_stack = self.build_middleware_stack()

Would be great if setup() could first check whether a handler for this exception exists already.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions