Skip to content

test(discord): regression guard for typing-indicator 429 handling (#29671) - #32761

Open
jameslcowan wants to merge 9568 commits into
NousResearch:mainfrom
jameslcowan:fix/test-discord-typing-429
Open

test(discord): regression guard for typing-indicator 429 handling (#29671)#32761
jameslcowan wants to merge 9568 commits into
NousResearch:mainfrom
jameslcowan:fix/test-discord-typing-429

Conversation

@jameslcowan

Copy link
Copy Markdown

Summary

Adds regression tests for the Discord typing-indicator 429 handling that landed in #29671. No production code change.

Related to #29671

What was happening

Before #29671, DiscordAdapter.send_typing's background loop died on the first exception from client.http.request, including any 429 rate-limit response. After a single 429, the typing bubble stayed dark for the rest of the turn even though the platform was happy to accept retries after retry_after seconds.

What the tests guard

  • test_429_with_retry_after_attribute_keeps_loop_alive: exception carries a numeric retry_after attribute (the shape discord.py emits via RateLimited). Verifies the loop honors the value, sleeps that long, and keeps trying across three consecutive 429s.
  • test_429_via_response_header_keeps_loop_alive: exception only exposes the retry budget via response.headers["Retry-After"] (the HTTPException fallback). Same behavior expected.
  • test_non_rate_limit_exception_still_exits_loop: a plain exception with no extractable retry_after must still terminate the loop, matching pre-fix behavior. Guards against an over-eager retry loop on genuinely unrecoverable errors.

Verification

Reverting the except Exception block in plugins/platforms/discord/adapter.py to its pre-#29671 shape (logger.debug(...); return) makes the two 429 tests fail with the "expected at least N attempts" assertions, confirming the guard actually traps the regression. The non-rate-limit test still passes under both versions, as intended.

Local test run

$ python -m pytest tests/gateway/test_discord_typing_429.py -v
collected 3 items
tests/gateway/test_discord_typing_429.py::test_429_with_retry_after_attribute_keeps_loop_alive PASSED
tests/gateway/test_discord_typing_429.py::test_429_via_response_header_keeps_loop_alive PASSED
tests/gateway/test_discord_typing_429.py::test_non_rate_limit_exception_still_exits_loop PASSED
============================== 3 passed in 0.20s ===============================

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P3 Low — cosmetic, nice to have platform/discord Discord bot adapter sweeper:blast-massive Sweeper blast radius: massive — everyone, every turn (invariant surface) sweeper:risk-automation Sweeper risk: may affect CI, automerge, label sync, or maintainer automation sweeper:risk-caching Sweeper risk: may break/degrade prompt caching or cache-key stability (invariant) sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/test Test coverage or test infrastructure

Projects

None yet

Development

Successfully merging this pull request may close these issues.