Skip to content

fix: catch CancelledError explicitly in all router streaming generators#7379

Open
ysolanky wants to merge 2 commits intomainfrom
ysolanky/compare-pr-fixes
Open

fix: catch CancelledError explicitly in all router streaming generators#7379
ysolanky wants to merge 2 commits intomainfrom
ysolanky/compare-pr-fixes

Conversation

@ysolanky
Copy link
Copy Markdown
Member

@ysolanky ysolanky commented Apr 6, 2026

Summary

Adds explicit asyncio.CancelledError handling to all SSE streaming generator functions across agent, team, and workflow routers.

Related: #7320, #7323, #7335

Problem: When a client disconnects during SSE streaming, asyncio.CancelledError (a BaseException subclass) propagates unhandled through the generators since they only catch Exception.

Fix: Add except asyncio.CancelledError: return before except Exception in all four streaming generators. This cleanly terminates the generator when the client is gone, without logging errors or trying to yield events to a disconnected client.

The team router previously used except BaseException which caught CancelledError but also swallowed GeneratorExit, SystemExit, and KeyboardInterrupt — the yield inside that handler would cause RuntimeError on GeneratorExit. This PR fixes the team router as well.

Router Function Before After
Agent agent_response_streamer except Exception + except CancelledError: return
Agent agent_continue_response_streamer except Exception + except CancelledError: return
Team team_response_streamer except BaseException except CancelledError: return + except Exception
Workflow workflow_response_streamer except Exception + except CancelledError: return

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Improvement
  • Model update
  • Other:

Checklist

  • Code complies with style guidelines
  • Ran format/validation scripts (./scripts/format.sh and ./scripts/validate.sh)
  • Self-review completed
  • Documentation updated (comments, docstrings)
  • Examples and guides: Relevant cookbook examples have been included or updated (if applicable)
  • Tested in clean environment
  • Tests added/updated (if applicable)

Duplicate and AI-Generated PR Check

  • I have searched existing open pull requests and confirmed that no other PR already addresses this issue
  • If a similar PR exists, I have explained below why this PR is a better approach
  • Check if this PR was entirely AI-generated (by Copilot, Claude Code, Cursor, etc.)

Additional Notes

PRs #7323 and #7335 both address the CancelledError issue in the agent router only. This PR takes a comprehensive approach: all four streaming generators now use the same pattern, and the team router's existing BaseException catch is narrowed to avoid swallowing GeneratorExit (which would cause RuntimeError on yield).

Align agent and workflow router streaming generators to catch
BaseException instead of Exception, matching the existing pattern
in the team router. This ensures asyncio.CancelledError and other
BaseException subclasses are properly handled when clients disconnect
during SSE streaming.
@ysolanky ysolanky requested a review from a team as a code owner April 6, 2026 21:08
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6a92c2ed5f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

)
yield format_sse_event(error_response)
except Exception as e:
except BaseException as e:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Avoid swallowing generator shutdown in streamers

Catching BaseException here causes GeneratorExit (raised when StreamingResponse closes an async generator on client disconnect/teardown) to enter this handler, and the subsequent yield triggers RuntimeError: async generator ignored GeneratorExit. This turns normal disconnects into error logs and can interfere with clean cancellation/shutdown behavior. In these streamer functions (agent_response_streamer, agent_continue_response_streamer, and workflow_response_streamer), catch asyncio.CancelledError explicitly if needed, but let GeneratorExit/other termination exceptions propagate.

Useful? React with 👍 / 👎.

Replace broad BaseException/Exception catch-all with targeted
asyncio.CancelledError handling in all four SSE streaming generators
(agent x2, team, workflow). CancelledError gets a clean return since
the client is already gone, while Exception still yields an error event.

This avoids swallowing GeneratorExit/SystemExit/KeyboardInterrupt
which the previous BaseException catch in the team router could hit.
@ysolanky ysolanky changed the title fix: consistent BaseException handling in all router streaming generators fix: catch CancelledError explicitly in all router streaming generators Apr 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant