From afecf9be560c61e5d1ae067bff315c82a5dc50cc Mon Sep 17 00:00:00 2001 From: Irfanuddin Date: Fri, 9 Sep 2022 01:21:58 +0530 Subject: [PATCH 1/8] fix: handle no body status codes in HTTPExceptions --- fastapi/exception_handlers.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fastapi/exception_handlers.py b/fastapi/exception_handlers.py index 2b286d71c7610..6c8db3d00aa45 100644 --- a/fastapi/exception_handlers.py +++ b/fastapi/exception_handlers.py @@ -1,13 +1,16 @@ from fastapi.encoders import jsonable_encoder from fastapi.exceptions import RequestValidationError +from fastapi.utils import is_body_allowed_for_status_code from starlette.exceptions import HTTPException from starlette.requests import Request -from starlette.responses import JSONResponse +from starlette.responses import JSONResponse, Response from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY -async def http_exception_handler(request: Request, exc: HTTPException) -> JSONResponse: +async def http_exception_handler(request: Request, exc: HTTPException) -> Response: headers = getattr(exc, "headers", None) + if not is_body_allowed_for_status_code(exc.status_code): + return Response(status_code=exc.status_code, headers=exc.headers) if headers: return JSONResponse( {"detail": exc.detail}, status_code=exc.status_code, headers=headers From f96a078bdaa5d8b37e9c7e6e608f67515894d850 Mon Sep 17 00:00:00 2001 From: Irfanuddin Date: Fri, 9 Sep 2022 01:39:09 +0530 Subject: [PATCH 2/8] fix: added tests for No Body Status Code Exception Handlers --- tests/test_starlette_exception.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/test_starlette_exception.py b/tests/test_starlette_exception.py index 859169d3cdad8..e239a7f0f6189 100644 --- a/tests/test_starlette_exception.py +++ b/tests/test_starlette_exception.py @@ -18,6 +18,18 @@ async def read_item(item_id: str): return {"item": items[item_id]} +@app.get("/http-no-body-statuscode-exception") +async def no_body_status_code_exception(): + raise HTTPException( + status_code=204, + ) + + +@app.get("/http-no-body-statuscode-with-detail-exception") +async def no_body_status_code_with_detail_exception(): + raise HTTPException(status_code=204, detail="I should not make it!") + + @app.get("/starlette-items/{item_id}") async def read_starlette_item(item_id: str): if item_id not in items: @@ -154,3 +166,15 @@ def test_get_starlette_item_not_found(): assert response.status_code == 404, response.text assert response.headers.get("x-error") is None assert response.json() == {"detail": "Item not found"} + + +def test_no_body_status_code_exception_handlers(): + response = client.get("/http-no-body-statuscode-exception") + assert response.status_code == 204 + assert not response.content + + +def test_no_body_status_code_with_detail_exception_handlers(): + response = client.get("/http-no-body-statuscode-with-detail-exception") + assert response.status_code == 204 + assert not response.content From 3c79e5b5592603c37c294ae9e5c8a2ddf2cbf44e Mon Sep 17 00:00:00 2001 From: Irfanuddin Date: Fri, 9 Sep 2022 01:45:45 +0530 Subject: [PATCH 3/8] fix: added schema for new tests to openapi json --- tests/test_starlette_exception.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/test_starlette_exception.py b/tests/test_starlette_exception.py index e239a7f0f6189..4f0c5e0f1ebd3 100644 --- a/tests/test_starlette_exception.py +++ b/tests/test_starlette_exception.py @@ -43,6 +43,36 @@ async def read_starlette_item(item_id: str): "openapi": "3.0.2", "info": {"title": "FastAPI", "version": "0.1.0"}, "paths": { + "/http-no-body-statuscode-exception": { + "get": { + "operationId": "no_body_status_code_exception_http_no_body_statuscode_exception_get", + "responses": { + "200": { + "content": {"application/json": {"schema": {}}}, + "description": "Successful " "Response", + } + }, + "summary": "No Body " "Status " "Code " "Exception", + } + }, + "/http-no-body-statuscode-with-detail-exception": { + "get": { + "operationId": "no_body_status_code_with_detail_exception_http_no_body_statuscode_with_detail_exception_get", + "responses": { + "200": { + "content": {"application/json": {"schema": {}}}, + "description": "Successful " "Response", + } + }, + "summary": "No " + "Body " + "Status " + "Code " + "With " + "Detail " + "Exception", + } + }, "/items/{item_id}": { "get": { "responses": { From c357017e20d94358b847c9f1d72f96ae6986570b Mon Sep 17 00:00:00 2001 From: Irfanuddin Date: Fri, 9 Sep 2022 01:47:13 +0530 Subject: [PATCH 4/8] fix: added schema for new tests to openapi json --- tests/test_starlette_exception.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_starlette_exception.py b/tests/test_starlette_exception.py index 4f0c5e0f1ebd3..e20bba112f696 100644 --- a/tests/test_starlette_exception.py +++ b/tests/test_starlette_exception.py @@ -27,7 +27,7 @@ async def no_body_status_code_exception(): @app.get("/http-no-body-statuscode-with-detail-exception") async def no_body_status_code_with_detail_exception(): - raise HTTPException(status_code=204, detail="I should not make it!") + raise HTTPException(status_code=204, detail="I should just disappear!") @app.get("/starlette-items/{item_id}") From f26af44027e588c10682a17f3acb8a69e12472d9 Mon Sep 17 00:00:00 2001 From: Irfanuddin Shafi Ahmed Date: Fri, 9 Sep 2022 03:01:27 +0530 Subject: [PATCH 5/8] Update tests/test_starlette_exception.py Co-authored-by: Marcelo Trylesinski --- tests/test_starlette_exception.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/test_starlette_exception.py b/tests/test_starlette_exception.py index e20bba112f696..8a95f820be615 100644 --- a/tests/test_starlette_exception.py +++ b/tests/test_starlette_exception.py @@ -20,9 +20,7 @@ async def read_item(item_id: str): @app.get("/http-no-body-statuscode-exception") async def no_body_status_code_exception(): - raise HTTPException( - status_code=204, - ) + raise HTTPException(status_code=204) @app.get("/http-no-body-statuscode-with-detail-exception") From fda6d888ca6100c2f64c78c16bd3684ee844af36 Mon Sep 17 00:00:00 2001 From: Irfanuddin Date: Fri, 9 Sep 2022 07:21:34 +0530 Subject: [PATCH 6/8] fix: used common headers --- fastapi/exception_handlers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastapi/exception_handlers.py b/fastapi/exception_handlers.py index 6c8db3d00aa45..1872cbf2613e5 100644 --- a/fastapi/exception_handlers.py +++ b/fastapi/exception_handlers.py @@ -10,7 +10,7 @@ async def http_exception_handler(request: Request, exc: HTTPException) -> Response: headers = getattr(exc, "headers", None) if not is_body_allowed_for_status_code(exc.status_code): - return Response(status_code=exc.status_code, headers=exc.headers) + return Response(status_code=exc.status_code, headers=headers) if headers: return JSONResponse( {"detail": exc.detail}, status_code=exc.status_code, headers=headers From d21ce644ba7817e08c6697cf4782195482137ecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sun, 11 Sep 2022 18:09:18 +0200 Subject: [PATCH 7/8] =?UTF-8?q?=F0=9F=8E=A8=20Format=20text=20in=20OpenAPI?= =?UTF-8?q?=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_starlette_exception.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/test_starlette_exception.py b/tests/test_starlette_exception.py index 8a95f820be615..2b6712f7b6c58 100644 --- a/tests/test_starlette_exception.py +++ b/tests/test_starlette_exception.py @@ -62,13 +62,7 @@ async def read_starlette_item(item_id: str): "description": "Successful " "Response", } }, - "summary": "No " - "Body " - "Status " - "Code " - "With " - "Detail " - "Exception", + "summary": "No Body Status Code With Detail Exception", } }, "/items/{item_id}": { From 1fe25cf6a6eb43c85631ffaf669be7df1f0da522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sun, 11 Sep 2022 18:09:40 +0200 Subject: [PATCH 8/8] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Simplify=20exception?= =?UTF-8?q?=20handler=20implementation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fastapi/exception_handlers.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/fastapi/exception_handlers.py b/fastapi/exception_handlers.py index 1872cbf2613e5..4d7ea5ec2e44b 100644 --- a/fastapi/exception_handlers.py +++ b/fastapi/exception_handlers.py @@ -11,12 +11,9 @@ async def http_exception_handler(request: Request, exc: HTTPException) -> Respon headers = getattr(exc, "headers", None) if not is_body_allowed_for_status_code(exc.status_code): return Response(status_code=exc.status_code, headers=headers) - if headers: - return JSONResponse( - {"detail": exc.detail}, status_code=exc.status_code, headers=headers - ) - else: - return JSONResponse({"detail": exc.detail}, status_code=exc.status_code) + return JSONResponse( + {"detail": exc.detail}, status_code=exc.status_code, headers=headers + ) async def request_validation_exception_handler(