Fix httpcore GeneratorExit in /v1/messages passthrough stream
Explicitly aclose aiter_lines() before the surrounding async with
blocks unwind, mirroring the prior fix in external_provider.py
(a41160d3) and cc757b78's RuntimeError suppression.
This commit is contained in:
parent
8e1aeddb56
commit
985e92a990
1 changed files with 29 additions and 14 deletions
|
|
@ -2672,21 +2672,36 @@ async def _anthropic_passthrough_stream(
|
||||||
json = body,
|
json = body,
|
||||||
timeout = 600,
|
timeout = 600,
|
||||||
) as resp:
|
) as resp:
|
||||||
async for raw_line in resp.aiter_lines():
|
# Explicitly manage the aiter_lines() iterator so it is
|
||||||
if await request.is_disconnected():
|
# closed in this task before the surrounding `async with`
|
||||||
cancel_event.set()
|
# blocks unwind the response / client. Without this, the
|
||||||
return
|
# inner httpcore byte-stream gets finalized by the GC in
|
||||||
if not raw_line or not raw_line.startswith("data: "):
|
# a different asyncio task on Python 3.13 + httpcore 1.x,
|
||||||
continue
|
# raising "Attempted to exit cancel scope in a different
|
||||||
data_str = raw_line[6:]
|
# task" and "async generator ignored GeneratorExit".
|
||||||
if data_str.strip() == "[DONE]":
|
lines_iter = resp.aiter_lines()
|
||||||
break
|
try:
|
||||||
|
async for raw_line in lines_iter:
|
||||||
|
if await request.is_disconnected():
|
||||||
|
cancel_event.set()
|
||||||
|
return
|
||||||
|
if not raw_line or not raw_line.startswith("data: "):
|
||||||
|
continue
|
||||||
|
data_str = raw_line[6:]
|
||||||
|
if data_str.strip() == "[DONE]":
|
||||||
|
break
|
||||||
|
try:
|
||||||
|
chunk = json.loads(data_str)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
continue
|
||||||
|
for line in emitter.feed_chunk(chunk):
|
||||||
|
yield line
|
||||||
|
finally:
|
||||||
try:
|
try:
|
||||||
chunk = json.loads(data_str)
|
await lines_iter.aclose()
|
||||||
except json.JSONDecodeError:
|
except RuntimeError:
|
||||||
continue
|
# Python 3.13 + httpcore 1.0.x asyncgen cleanup
|
||||||
for line in emitter.feed_chunk(chunk):
|
pass
|
||||||
yield line
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("anthropic_messages passthrough stream error: %s", e)
|
logger.error("anthropic_messages passthrough stream error: %s", e)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue