Skip to content

test(txn): pin that commit retry exhaustion rejects the awaited request chain#1861

Open
kriszyp wants to merge 4 commits into
mainfrom
kris/retry-exhaustion-propagation
Open

test(txn): pin that commit retry exhaustion rejects the awaited request chain#1861
kriszyp wants to merge 4 commits into
mainfrom
kris/retry-exhaustion-propagation

Conversation

@kriszyp

@kriszyp kriszyp commented Jul 18, 2026

Copy link
Copy Markdown
Member

Summary

Test-only. Closes out the #1785 follow-up ("retry-exhaustion error never reaches the HTTP caller"): investigation showed the propagation is intact on main — the 5.1.19 field symptom was retry-cycle latency (pre-#1696 per-record txn-log scans blocking the event loop) outliving the client's socket, not a swallowed rejection. These tests pin the invariant so it stays true:

  • All three native conflict-signaling paths (ERR_TRY_AGAIN, ERR_BUSY rejections; coordinated RETRY_NOW sentinel) reject the awaited transaction() promise with the ServerError (statusCode 500) after exactly MAX_RETRIES + 1 native attempts, in bounded time, with no unhandled rejection.

Where to look

  • The two rejection-path tests run the real quadratic backoff (~19.5s each) — deliberate, since bounded wall-clock is part of the invariant (the 5.1.19 failure mode was exactly this taking ~7 minutes). If the ~40s suite cost is unwanted, faking timers or a test-scoped MAX_RETRY_DELAY_MS override are the alternatives (raised by the Gemini review; left as-is intentionally).
  • The commit stub is scoped to the test table's native db handle: a global stub poisons background hdb_analytics aggregation transactions, which spawn their own 40-retry chains and pollute the attempt count (708 attempts observed).

Generated by an LLM (Claude Fable 5), supervised by Kris.

🤖 Generated with Claude Code

kriszyp and others added 3 commits July 18, 2026 07:16
…st chain

Investigating harper#1785's follow-up (retry-exhaustion error never reaches
the caller): on main the propagation is intact — these tests pin it so it
stays that way. All three native conflict-signaling paths are covered
(ERR_TRY_AGAIN, ERR_BUSY, coordinated RETRY_NOW): the awaited transaction()
promise must reject with the ServerError (statusCode 500) after exactly
MAX_RETRIES + 1 attempts, within bounded time, with no unhandled rejection.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s (cross-model review)

Codex review: unhandledRejection is delivered on a later event-loop turn, so
asserting immediately (and removing the listener in the after hook) could let
a leaked rejection escape the check.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…el review)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kriszyp
kriszyp requested a review from cb1kenobi July 18, 2026 13:55

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new test suite, requestPathRetryExhaustion.test.js, to verify that request-path transactions reject properly with a 500 ServerError when commit retries are exhausted, preventing silent hangs. The review feedback highlights two important improvements: first, managing prototype stub cleanups via an afterEach hook to prevent test pollution in case of timeouts; second, configuring the background delay timers with { ref: false } to ensure they do not keep the Node.js event loop active after the tests finish.

Comment thread unitTests/resources/requestPathRetryExhaustion.test.js
Comment thread unitTests/resources/requestPathRetryExhaustion.test.js
Comment thread unitTests/resources/requestPathRetryExhaustion.test.js Outdated
@claude

claude Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Reviewed; no blockers found.

… review)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kriszyp
kriszyp marked this pull request as ready for review July 18, 2026 14:28
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