Repository navigation
fix(azure): surface skipped consumption recommendations as a typed partial-result error - #366
Merged
Merged
Conversation
…rtial-result error A non-USD billing currency or an unpriceable SKU was dropped with only a log line, so an EUR or GBP account looked like it had no savings. The skips are now recorded on a context-carried SkipLog and returned from GetRecommendations as *PartialResultError alongside the recommendations that did succeed. Closes #362 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
Warning Review limit reached
This review includes 13 billable files and costs up to $3.25.
Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing. Or wait 7 minutes for your next included review. View limit details
Comment |
This was referenced Oct 13, 2026
… partial result PartialResultError was only reachable from the internal package and the multi-subscription merge counted any error as a failed subscription, dropping its recommendations. Export the type and AsPartialResult, give it a Partial() method, and aggregate skips across subscriptions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
Author
|
Independent review (claude-opus-5-5) of 2de6006: APPROVE Re-review after my block of 83f14ed. Review only; no Azure calls needed. The earlier blockers are fixed:
Evidence (local, fresh clone, macOS, fixture-based):
Non-blocking:
|
Member
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #362
Root cause
providers/azure/internal/recommendations/consumption.goExtractConsumptionOrSkip/AppendConsumptionVariantslogged and returned nil for non-USD amounts and unpriceable SKUs. An EUR/GBP account got zero recommendations and a nil error.Change
SkipLogcarried on the collection context (WithSkipLog); both skip paths record into it.ExtractConsumptionOrSkipnow takesctx(one-line call-site changes in the 7 service converters, plus a ctx param on synapse's converter).GetRecommendationsreturns the successful recommendations and a*azrecs.PartialResultErrorlisting the skips.Choice of error variant
A typed partial-result error with the good rows retained, not a hard failure: one bad SKU must not discard the rest of a run, but must not be silent either. Callers use
errors.Asto keep the recs; callers that treat any error as failure see the problem. A fully skipped account returns empty recs plus the error. I could not inspect platform/MCP callers (code search returned nothing for those repos), so how they treatrecs != nil && err != nilis unverified.Evidence (fixture-based; modern payloads built from armconsumption types, no live Azure data)
Before (recommendations.go reverted, new test kept):
After:
go test ./...in providers/azure passes;go vetandGOWORK=off go build ./...clean; pre-commit hooks (gocyclo, vet) pass. golangci-lint could not run locally (installed binary built with go1.26, repo needs 1.27); relying on CI.🤖 Generated with Claude Code
Update after review
PartialResultErroris now exported fromproviders/azure(type alias) withAsPartialResult(err)and aPartial() boolmethod, so it can satisfy the planned cross-providerAsPartialinterface match (G6a-1 reshapesPartial()to whateverreccontractspecifies).PartialResultError. A real subscription failure still yieldsPartialSubscriptionFailureError; if both occur in one sweep, the failure error wins and the skips are logged only.TestMultiSubscriptionRecommendationsClient_PartialResultKeepsRecommendationsreproduces the reviewer probe (2 subs, 1 rec + 1 skip each, now 2 recs and a partial error).Caller changes needed (not in this PR; architect P1/C-steps)
internal/scheduler/scheduler.gotolerateIncompleteSweep(~1019): also tolerateAsPartialResult(orreccontract.AsPartial).cmd/multi_service_helpers.go(~627): same.search_recommendations.go(~266): same.Until then, a caller that only tolerates
PartialSubscriptionFailureErrortreats a skip as a hard error for that run.