8000 🐛 Preserve traceback when an exception is raised in sync dependency with `yield` by sombek · Pull Request #5823 · fastapi/fastapi · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
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

🐛 Preserve traceback when an exception is raised in sync dependency with yield #5823

Merged
merged 4 commits into from
Dec 3, 2024

Conversation

sombek
Copy link
Contributor
@sombek sombek commented Dec 30, 2022

There is a missing of traceback when an exception raised in contextmanager_in_threadpool
Happens on Python 3.11

I noticed the exception.traceback gets flushed after exiting the context manager.

There is an issue is opened #5740

Edit by @Kludex :

@github-actions
Copy link
Contributor

📝 Docs preview for commit 202133b at: https://63af5d1c07bec913f8d350a9--fastapi.netlify.app

@MohammedAlhajji
Copy link

great workaround. thanks!

@github-actions
Copy link
Contributor

📝 Docs preview for commit 411ad02 at: https://63af6350238dde190a34aafc--fastapi.netlify.app

@MrSalman333
Copy link

Nice work!

We didn't upgrade to 3.11 because of this.
Thankss

Copy link
Contributor
@iudeen iudeen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks neat! And thanks for the tests as well!

@sombek
Copy link
Contributor Author
sombek commented Jan 3, 2023

@iudeen @yezz123 Usually, how long it takes you guys to merge a PR?

@yezz123
Copy link
Contributor
yezz123 commented Jan 3, 2023

@iudeen @yezz123 Usually, how long it takes you guys to merge a PR?

Mainly @tiangolo will review it after adding a flag of awaiting review so just wait it's will be reviewed asap

@github-actions
Copy link
Contributor
github-actions bot commented Jan 8, 2023

📝 Docs preview for commit efd395c at: https://63bab4ceb11ed37e88ef871e--fastapi.netlify.app

@suzaku
Copy link
suzaku commented Jan 11, 2023

I patched your change with the following code and now the traceback's back. Thanks.

from contextlib import asynccontextmanager as asynccontextmanager
from typing import AsyncGenerator, ContextManager, TypeVar

import anyio
from anyio import CapacityLimiter
from starlette.concurrency import run_in_threadpool as run_in_threadpool  # noqa

_T = TypeVar("_T")

# 
@asynccontextmanager
async def contextmanager_in_threadpool(
    cm: ContextManager[_T],
) -> AsyncGenerator[_T, None]:
    # blocking __exit__ from running waiting on a free thread
    # can create race conditions/deadlocks if the context manager itself
    # has it's own internal pool (e.g. a database connection pool)
    # to avoid this we let __exit__ run without a capacity limit
    # since we're creating a new limiter for each call, any non-zero limit
    # works (1 is arbitrary)
    exit_limiter = CapacityLimiter(1)
    try:
        yield await run_in_threadpool(cm.__enter__)
    except Exception as e:
        traceback_ = e.__traceback__
        ok = bool(
            await anyio.to_thread.run_sync(
                cm.__exit__, type(e), e, None, limiter=exit_limiter
            )
        )
        if not ok:
            if e.__traceback__ is None:
                e.__traceback__ = traceback_
            raise e
    else:
        await anyio.to_thread.run_sync(
            cm.__exit__, None, None, None, limiter=exit_limiter
        )

# Run this before starting anything FastAPI related
from fastapi.dependencies import utils
utils.contextmanager_in_threadpool = contextmanager_in_threadpool

@github-actions
Copy link
Contributor

📝 Docs preview for commit 45317a3 at: https://63ccf7d40fb8da632502fbec--fastapi.netlify.app

@sombek
Copy link
Contributor Author
sombek commented Feb 2, 2023

@tiangolo Any idea when can we merge this?

@github-actions
Copy link
Contributor

📝 Docs preview for commit 11fd1ce at: https://63eb512c20977663c11a0846--fastapi.netlify.app

@etsvetanov
Copy link

Does this PR need additional work or help?

@tiangolo tiangolo added the feature New feature or request label Oct 2, 2023
@Kludex
Copy link
Member
Kludex commented Dec 2, 2024

Copied code from #8428 (comment), thanks @guillaumegenthial

@@ -1,7 +1,7 @@
from contextlib import asynccontextmanager as asynccontextmanager
from typing import AsyncGenerator, ContextManager, TypeVar

import anyio
import anyio.to_thread
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick.

@Kludex Kludex changed the title Keeping traceback when exception raised in contextmanager_in_threadpool Keeping traceback when exception raised in contextmanager_in_threadpool Dec 2, 2024
Comment on lines +87 to +88
assert str(last_frame.path) == __file__
assert last_frame.lineno == raise_value_error.__code__.co_firstlineno
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you revert the changes, you can verify that the dependency will not be the last frame (or in any frame, because it will not be present).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, great, I did this to verify. 🤓

@tiangolo
Copy link
Member
tiangolo commented Dec 3, 2024

Great job @sombek, thank you! 🚀

And thanks @Kludex for the help, tweaks, and bringing my attention to this on the private channels. 🙇

This will be available in version 0.115.6 released in the next hours. 🚀

@tiangolo tiangolo added bug Something isn't working and removed feature New feature or request labels Dec 3, 2024
@tiangolo tiangolo changed the title Keeping traceback when exception raised in contextmanager_in_threadpool 🐛 Preserve traceback when exception is raised in sync dependency with yield Dec 3, 2024
@tiangolo tiangolo merged commit 4f81575 into fastapi:master Dec 3, 2024
32 checks passed
@tiangolo tiangolo changed the title 🐛 Preserve traceback when exception is raised in sync dependency with yield 🐛 Preserve traceback when an exception is raised in sync dependency with yield Dec 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Traceback stack does not show exact place of error
0