Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: HTTPExceptions are not being handled correctly when dependency processing is offloaded to a TaskGroup #2594

Closed
1 of 4 tasks
smithk86 opened this issue Nov 1, 2023 · 2 comments · Fixed by #2596
Closed
1 of 4 tasks
Labels
Bug 🐛 This is something that is not working as expected

Comments

@smithk86
Copy link
Contributor

smithk86 commented Nov 1, 2023

Description

I have an application which uses heavily nested dependencies. Many of those dependencies have validation logic which throws HTTPExceptions so that users can update their requests and try again.

I am upgrading this from Starlite v1 and have hit an issue with how dependencies are handled when nesting occurs. It appears nested dependencies are processed concurrently within an anyio.TaskGroup instance. If any exception occurs in This instance of create_task_group, they all result in a GroupException. Because of this, any HTTPExceptions thrown from inside the dependency logic gets yeeted into the void and the requester never sees it.

URL to code causing the issue

No response

MCVE

from litestar import Litestar
from litestar.di import Provide
from litestar.handlers import get
from litestar.exceptions import HTTPException


def get_dependency_child1() -> str:
    raise HTTPException(detail="No sir, I don't like it.", status_code=400)


def get_dependency_child2() -> str:
    return "OK"


def get_dependency_parent(
    dependency_child1: str,
    dependency_child2: str,
) -> str:
    return dependency_child1 + dependency_child2


@get(
    path="/",
    dependencies={
        "dependency_child1": Provide(get_dependency_child1, sync_to_thread=False),
        "dependency_child2": Provide(get_dependency_child2, sync_to_thread=False),
        "dependency_parent": Provide(get_dependency_parent, sync_to_thread=False),
    },
)
def route(dependency_parent: str) -> str:
    return dependency_parent


app = Litestar(route_handlers=[route], debug=True)

Steps to reproduce

No response

Screenshots

"![SCREENSHOT_DESCRIPTION](SCREENSHOT_LINK.png)"

Logs

ERROR - 2023-11-01 15:58:04,508 - litestar - config - exception raised on http connection to route /

  + Exception Group Traceback (most recent call last):
  |   File "/tmp/litestarTest/.venv/lib/python3.10/site-packages/litestar/middleware/exceptions/middleware.py", line 191, in __call__
  |     await self.app(scope, receive, send)
  |   File "/tmp/litestarTest/.venv/lib/python3.10/site-packages/litestar/routes/http.py", line 81, in handle
  |     response = await self._get_response_for_request(
  |   File "/tmp/litestarTest/.venv/lib/python3.10/site-packages/litestar/routes/http.py", line 133, in _get_response_for_request
  |     return await self._call_handler_function(
  |   File "/tmp/litestarTest/.venv/lib/python3.10/site-packages/litestar/routes/http.py", line 153, in _call_handler_function
  |     response_data, cleanup_group = await self._get_response_data(
  |   File "/tmp/litestarTest/.venv/lib/python3.10/site-packages/litestar/routes/http.py", line 185, in _get_response_data
  |     cleanup_group = await parameter_model.resolve_dependencies(request, kwargs)
  |   File "/tmp/litestarTest/.venv/lib/python3.10/site-packages/litestar/_kwargs/kwargs_model.py", line 393, in resolve_dependencies
  |     async with create_task_group() as task_group:
  |   File "/tmp/litestarTest/.venv/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 664, in __aexit__
  |     raise BaseExceptionGroup(
  | exceptiongroup.ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
  +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    |   File "/tmp/litestarTest/.venv/lib/python3.10/site-packages/litestar/_kwargs/dependencies.py", line 66, in resolve_dependency
    |     value = await dependency.provide(**dependency_kwargs)
    |   File "/tmp/litestarTest/.venv/lib/python3.10/site-packages/litestar/di.py", line 84, in __call__
    |     value = self.dependency.value(**kwargs)
    |   File "/tmp/litestarTest/di_test_app.py", line 8, in get_dependency_child1
    |     raise HTTPException(detail="No sir, I don't like it.", status_code=400)
    | litestar.exceptions.http_exceptions.HTTPException: 400: No sir, I don't like it.
    +------------------------------------
  + Exception Group Traceback (most recent call last):
  |   File "/tmp/litestarTest/.venv/lib/python3.10/site-packages/litestar/middleware/exceptions/middleware.py", line 191, in __call__
  |     await self.app(scope, receive, send)
  |   File "/tmp/litestarTest/.venv/lib/python3.10/site-packages/litestar/routes/http.py", line 81, in handle
  |     response = await self._get_response_for_request(
  |   File "/tmp/litestarTest/.venv/lib/python3.10/site-packages/litestar/routes/http.py", line 133, in _get_response_for_request
  |     return await self._call_handler_function(
  |   File "/tmp/litestarTest/.venv/lib/python3.10/site-packages/litestar/routes/http.py", line 153, in _call_handler_function
  |     response_data, cleanup_group = await self._get_response_data(
  |   File "/tmp/litestarTest/.venv/lib/python3.10/site-packages/litestar/routes/http.py", line 185, in _get_response_data
  |     cleanup_group = await parameter_model.resolve_dependencies(request, kwargs)
  |   File "/tmp/litestarTest/.venv/lib/python3.10/site-packages/litestar/_kwargs/kwargs_model.py", line 393, in resolve_dependencies
  |     async with create_task_group() as task_group:
  |   File "/tmp/litestarTest/.venv/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 664, in __aexit__
  |     raise BaseExceptionGroup(
  | exceptiongroup.ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
  +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    |   File "/tmp/litestarTest/.venv/lib/python3.10/site-packages/litestar/_kwargs/dependencies.py", line 66, in resolve_dependency
    |     value = await dependency.provide(**dependency_kwargs)
    |   File "/tmp/litestarTest/.venv/lib/python3.10/site-packages/litestar/di.py", line 84, in __call__
    |     value = self.dependency.value(**kwargs)
    |   File "/tmp/litestarTest/di_test_app.py", line 8, in get_dependency_child1
    |     raise HTTPException(detail="No sir, I don't like it.", status_code=400)
    | litestar.exceptions.http_exceptions.HTTPException: 400: No sir, I don't like it.
    +------------------------------------
INFO:     127.0.0.1:54512 - "GET / HTTP/1.1" 500 Internal Server Error

Litestar Version

2.2.1

Platform

  • Linux
  • Mac
  • Windows
  • Other (Please specify in the description above)

Note

While we are open for sponsoring on GitHub Sponsors and
OpenCollective, we also utilize Polar.sh to engage in pledge-based sponsorship.

Check out all issues funded or available for funding on our Polar.sh Litestar dashboard

  • If you would like to see an issue prioritized, make a pledge towards it!
  • We receive the pledge once the issue is completed & verified
  • This, along with engagement in the community, helps us know which features are a priority to our users.
Fund with Polar
@smithk86 smithk86 added Bug 🐛 This is something that is not working as expected Triage Required 🏥 This requires triage labels Nov 1, 2023
@peterschutt
Copy link
Contributor

yeeted into the void

😂

Thanks for reporting!

@provinzkraut
Copy link
Member

provinzkraut commented Nov 1, 2023

yeeted into the void

😂

Thanks for reporting!

Yeah, we should avoid such void-yeeting.

Probably want to make sure things get properly re-raised.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug 🐛 This is something that is not working as expected
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants