-
Notifications
You must be signed in to change notification settings - Fork 17.2k
Fix spurious "Failed to detach context" error on Execution API disconnects #68039
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -253,9 +253,25 @@ async def _extract_w3c_trace_context( | |
| token = otel_context.attach(ctx) | ||
| try: | ||
| yield | ||
| finally: | ||
| except GeneratorExit: | ||
| # Cross-task force-close (client disconnect / request cancellation): the | ||
| # finalizer runs in a different asyncio Task — and thus a different | ||
| # contextvars.Context — than attach did, so detaching the token would raise | ||
| # "Token was created in a different Context" (which OTel logs at ERROR before | ||
| # any suppression here could see it). The attached Context is being discarded | ||
| # with the dying task, so detaching is unnecessary; skip it and re-raise. | ||
| raise | ||
| except BaseException: | ||
| # A route handler raised: FastAPI throws the exception into this generator at | ||
| # the yield, in the SAME task that attach ran in. Detach so the upstream trace | ||
| # context does not stay attached for the exception handler, the error response, | ||
| # and any spans/logs emitted while unwinding. Suppress any detach error so it | ||
| # cannot mask the original exception being propagated. | ||
| with contextlib.suppress(Exception): | ||
| otel_context.detach(token) | ||
| raise | ||
| else: | ||
| otel_context.detach(token) | ||
|
Comment on lines
254
to
+274
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you share before/after logs from an actual disconnect? The tests assert detach isn't called, but the spurious line is logged inside OTel's own Minor and optional: rather than splitting on attached_in = asyncio.current_task()
try:
yield
finally:
if asyncio.current_task() is attached_in:
otel_context.detach(token)Same result, one branch. Not a blocker. |
||
|
|
||
|
|
||
| def _inject_trace_context_dep(routes, mode: str) -> None: | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.