Skip to content

docs(azure): correct two retry comments that #1767 made false - #1792

Merged
cristim merged 1 commit into
mainfrom
fix/1767-followup-stale-retry-comments
Aug 9, 2026
Merged

cristim merged 1 commit into
mainfrom
fix/1767-followup-stale-retry-comments

Conversation

@cristim

@cristim cristim commented Aug 8, 2026 •

Copy link
Copy Markdown
Member

Comment-only follow-up to #1767, which merged (d6e60f637) before these two fixes landed. No behavior change; the lint set diff is byte-identical to main.

What was wrong

Both comments make exhaustiveness claims that stopped being true when #1767 added a second retry trigger.

1. purchase_test.go — flagged by CodeRabbit on #1767, unfixed at merge time:

// doPurchase's error text is the ONLY input to IsSessionTimeout, and
// DoPurchaseTwoStep retries only when that predicate matches.

Neither half holds. The loop also retries on errors.Is(err, errRetryabilityUnknown).

2. DoPurchaseTwoStep's own doc — nobody flagged this one:

// On a "Session timed out" 400 from the purchase endpoint (Azure has retired
// the session) it re-runs calculatePrice from scratch (up to
// purchaseMaxAttempts total attempts).
// Other 4xx/5xx errors are returned immediately without retry.

That omits the second trigger entirely, in the production doc a caller reads to decide whether a failure will be retried. Found by sweeping the whole #1767 diff for the same class rather than fixing only the reported line.

What they say now

Each leads with the current rule and keeps the pre-fix explanation marked as the reason the test exists, rather than past-tensing the old text into history. A reader who stops after the first paragraph should come away with something true.

DoPurchaseTwoStep now enumerates both retry cases and states plainly that everything else — including a cleanly read 4xx and any 5xx — returns without retry.

Why this is worth its own PR

Exhaustiveness claims are what readers rely on to decide they do not need to check, so a stale one is worse than no comment. In this repo that class has already cost real defects: #1757, a live CSRF hole, survived behind a parity claim that was not true, and #1764's getAccountScope godoc described the inverse of its behavior after a change.

#1767 spent two review rounds removing an assertion that read as a guarantee it did not provide. Leaving comments that read as guarantees they no longer provide is the same defect in prose.

Gates

providers/azure: gofmt clean, build, vet, go test -race -count=1 ./... green. Root: build, vet, gocyclo -over 10 -ignore "_test\.go" . exit 0 empty, golangci-lint v2.10.1 exit 0 with a genuine 0 issues. line (both asserted).

providers/azure lint set diff vs main: 589 vs 589, zero only-in-HEAD, zero only-in-BASE — byte-identical, as a comment-only change should be.

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling of purchase requests when a 400 response body cannot be read, allowing eligible requests to be retried.
    • Preserved non-retryable behavior for clearly readable 4xx responses and all 5xx responses.
    • Improved retry decisions by relying on response context rather than error message text alone.

Comment-only. Both make exhaustiveness claims that stopped being true when
#1767 added a second retry trigger, and both now describe the current rule.

purchase_test.go said doPurchase's error text is "the ONLY input to
IsSessionTimeout, and DoPurchaseTwoStep retries only when that predicate
matches". Neither half holds: the loop also retries on
errors.Is(err, errRetryabilityUnknown). CodeRabbit flagged this on #1767; the
PR merged before the fix landed, so the claim is live on main.

DoPurchaseTwoStep's own doc had the same defect and nobody flagged it. It said
retry happens on a "Session timed out" 400 and that "Other 4xx/5xx errors are
returned immediately without retry", which omits the second trigger entirely.
Found by sweeping the whole #1767 diff for the same class rather than fixing
only the line that was reported. It now enumerates both cases and states that
everything else -- including a cleanly read 4xx and any 5xx -- returns without
retry.

Rather than past-tensing the old text, each comment leads with the current
rule and keeps the pre-fix explanation marked as the reason the test exists.
A reader who stops after the first paragraph should come away with something
true.

Exhaustiveness claims are what readers rely on to decide they need not check,
so a stale one is worse than none: #1757 (a live CSRF hole) survived behind a
parity claim that was not true, and #1764's getAccountScope godoc described
the inverse of its behavior after a change.

Refs #1767, #1766

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@cristim cristim added triaged Item has been triaged priority/p3 Polish / idea / may never ship severity/low Minor harm urgency/eventually No deadline impact/internal Team-internal only effort/xs Trivial / one-liner type/chore Maintenance / non-user-visible labels Aug 8, 2026
@coderabbitai

coderabbitai Bot commented Aug 8, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 769929e7-f145-4fc1-8bd3-5a859b96cc42

📥 Commits

Reviewing files that changed from the base of the PR and between d6e60f6 and ae3439b.

📒 Files selected for processing (2)
  • providers/azure/services/internal/reservations/purchase.go
  • providers/azure/services/internal/reservations/purchase_test.go

📝 Walkthrough

Walkthrough

The PR updates DoPurchaseTwoStep documentation and regression-test comments to describe retries for unreadable 400 responses, recognized session-timeout errors, and immediate returns for cleanly read 4xx and 5xx responses.

Changes

Azure purchase retry documentation

Layer / File(s) Summary
Document retry behavior
providers/azure/services/internal/reservations/purchase.go, providers/azure/services/internal/reservations/purchase_test.go
The documentation now covers the three-attempt limit for unreadable 400 responses, non-retriable cleanly read 4xx and 5xx responses, the errRetryabilityUnknown marker, and separate validation of error reporting and retry attempts.

Estimated code review effort: 1 (Trivial) | ~3 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the Azure documentation-only changes to correct two retry comments.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ 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/1767-followup-stale-retry-comments

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

@cristim

cristim commented Aug 9, 2026

Copy link
Copy Markdown
Member Author

Merging. Comment-only correction to two retry claims that #1767 falsified.

CodeRabbit caught one; the sweep found the one that mattered more, and CR did not flag it.

The reported line was a test function preamble. I initially escalated it, then downgraded on the reasoning that stale prose sitting next to a correct authoritative statement is not misleading. That reasoning was right and I applied it to the wrong file. DoPurchaseTwoStep's own doc comment said:

// Other 4xx/5xx errors are returned immediately without retry.

That is production documentation a caller reads from outside the package to decide whether a failure will be retried — precisely the thing someone relies on to skip a check. After #1767 it omitted the second retry trigger entirely.

The distinction that matters, and the rule taken from it: a stale comment blocks when something relies on it to skip a check. Security-control claims, godoc on a seam, a named test guarantee. Explanatory prose adjacent to a correct current statement does not. Three real defects here came from the first category — #1757's live CSRF vulnerability survived because a comment asserted parity that did not exist; #1764's godoc asserted the inverse of what its function returned; #1758's docstring named a backstop that can never fire.

The sweep is what found it. The finding was described as a class rather than a line, so the whole #1767 diff was swept rather than the reported site patched. The rest of its exhaustiveness language was then verified against the code — "the only scenario #1766 reports", "there is no recheck between attempts", "Success is decided by the status code alone", "and to nothing else" — all true, with the sentinel confirmed attached at exactly one site. That verification is what separates a sweep from a spot check.

Both comments lead with the current rule rather than past-tensing. CR's proposed diff was accurate but would have left the reader with history and no rule; someone who stops after the first paragraph should still come away with something true. The pre-fix explanation stays, marked as the reason the test exists.

The lint set diff is 589 vs 589, zero on either side — byte-identical, which is what a comment-only change must produce and the check that proves it is comment-only.

Gates: providers/azure gofmt/build/vet clean, go test -race green; root build, vet, gocyclo exit 0 empty, golangci-lint v2.10.1 exit 0 with a genuine 0 issues. line.

@cristim
cristim merged commit a37e147 into main Aug 9, 2026
20 checks passed
@cristim
cristim deleted the fix/1767-followup-stale-retry-comments branch October 17, 2026 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/xs Trivial / one-liner impact/internal Team-internal only priority/p3 Polish / idea / may never ship severity/low Minor harm triaged Item has been triaged type/chore Maintenance / non-user-visible urgency/eventually No deadline

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant