Skip to content

fix(hybrid): re-raise CancelledError in platform attempt walker - #511

Merged
njbrake merged 2 commits into
mainfrom
fix/hybrid-cancelled-request-not-provider-failure
Aug 6, 2026
Merged

fix(hybrid): re-raise CancelledError in platform attempt walker#511
njbrake merged 2 commits into
mainfrom
fix/hybrid-cancelled-request-not-provider-failure

Conversation

@njbrake

@njbrake njbrake commented Aug 5, 2026

Copy link
Copy Markdown
Member

Description

run_platform_attempts catches BaseException around each attempt so a provider client raising outside the Exception hierarchy still falls through to the next candidate. That catch also swallows asyncio.CancelledError, which a disconnected caller produces: it gets classified as an unknown upstream error, an abandoned attempt is recorded against a provider that answered fine, and it is raised as a provider-failure HTTP exception that suppresses the cancellation the server is waiting to unwind.

This adds an except asyncio.CancelledError: raise guard ahead of the broad catch, mirroring the standalone walker fix from #492 (_attempts.py). A unit test asserts the cancellation propagates and no abandoned-attempt row is recorded.

PR Type

  • Bug Fix

Relevant issues

Fixes #501

Checklist

  • I understand the code I am submitting.
  • I have added or updated tests that cover my change (tests/unit, tests/integration).
  • I ran the Definition of Done checks locally (make lint, make typecheck, make test).
  • Documentation was updated where necessary.
  • If the API contract changed, I regenerated the OpenAPI spec (uv run python scripts/generate_openapi.py).

AI Usage

  • AI was used for drafting/refactoring.

AI Model/Tool used: DeepSeek V4 Flash

Any additional AI details you'd like to share:

The fix and regression test mirror the standalone walker change in #492. Verified the new test fails without the guard and passes with it.

NOTE:
When responding to reviewer questions, please respond yourself rather than copy/pasting reviewer comments into an AI and pasting back its answer. We want to discuss with you, not your AI :)

  • I am an AI Agent filling out this form (check box if true)

A disconnected caller raises asyncio.CancelledError, which derives from
BaseException, so the broad catch meant to let non-Exception provider
clients fall through to the next candidate instead classified the
cancellation as an "unknown" upstream error, recorded an abandoned
attempt against a provider that answered fine, and converted it into a
provider-failure HTTP exception that suppressed the cancellation.

Guard the broad catch with a re-raise, mirroring the standalone walker
fix in #492. Add a unit test asserting the cancellation propagates and
no abandoned-attempt row is recorded.

Fixes #501
@njbrake
njbrake temporarily deployed to integration-tests August 5, 2026 21:20 — with GitHub Actions Inactive
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

run_platform_attempts now re-raises asyncio.CancelledError before broad exception handling. A unit test confirms cancellation propagation without provider-failure handling, fallback, or abandoned-attempt metrics.

Changes

Cancellation propagation

Layer / File(s) Summary
Cancellation guard and regression coverage
src/gateway/api/routes/_platform.py, tests/unit/test_run_platform_attempts.py
The platform attempt runner propagates asyncio.CancelledError. The regression test verifies that cancellation does not trigger provider-failure handling or abandoned-attempt metrics.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • mozilla-ai/otari#326: Both changes modify run_platform_attempts and its tests, but this change addresses cancellation propagation.

Suggested reviewers: agpituk

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The change re-raises asyncio.CancelledError and adds regression coverage for propagation and missing abandoned-attempt records, satisfying issue #501.
Out of Scope Changes check ✅ Passed The code and test changes are limited to cancellation handling in the hybrid platform attempt walker and its regression coverage.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title uses the valid Conventional Commit type fix, uses imperative mood, clearly describes the cancellation fix, and is 63 characters long.
Description check ✅ Passed The description explains the bug and fix, identifies the issue, documents testing, and completes the relevant checklist and AI usage sections.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/hybrid-cancelled-request-not-provider-failure
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch fix/hybrid-cancelled-request-not-provider-failure

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai
coderabbitai Bot requested a review from agpituk August 5, 2026 21:20
@njbrake
njbrake removed the request for review from agpituk August 6, 2026 12:44
@njbrake
njbrake temporarily deployed to integration-tests August 6, 2026 12:45 — with GitHub Actions Inactive
@njbrake
njbrake merged commit e7d9370 into main Aug 6, 2026
5 checks passed
@njbrake
njbrake deleted the fix/hybrid-cancelled-request-not-provider-failure branch August 6, 2026 12:54
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.

Hybrid walker turns a cancelled request into a provider failure

1 participant