PROD-10283 - #5027
Conversation
…products API ground-level-mothership 2.2.1 only caches successful products responses, so every read of the update_plugins/update_themes site transients re-fired a live GET /products?_embed=version-latest after any API failure - the 2026-08-11 retry storm. Backport of the 8.x/9.x error handling onto the 2.2.1 path, implemented entirely in BB_Addons_Manager by routing the shared AddonsManager::$productsApiClient through a backoff wrapper: - Cache failed lookups for 5 minutes minimum (8.x ERROR_TTL_MINUTES), capped at 1 hour, and skip live API calls while the backoff is active. - Honor Retry-After / X-RateLimit-Reset via the existing license rate-limit header capture; fail fast without HTTP while a recorded block is active. - Serve the last successful catalog during the error window (8.x/9.x stale-while-error) so update checks survive short API blips. - Claim the retry before the live call so concurrent requests cannot burst at the backoff window boundary; discard corrupt far-future reset values. - Lift the backoff wherever the products cache is cleared (license change, activation, reset, manual Refresh Add-ons). - Guard placeholder cards and the Help-tab tier probe against misreading an API outage as "not in your plan" via productsApiErrored().
…tale catalog on the cached-error path Follow-up to the PROD-10283 code review: - catch ( \Throwable ) instead of \Exception: the strictly-typed vendor client can raise TypeError (e.g. a malformed error payload hitting implode()), which must feed the error backoff instead of fataling the update_plugins/update_themes transient filters. - Apply the same stale-catalog fallback on the cached-error early return as on the live-failure and rate-limit paths, so readers landing inside an open backoff window (or while another request is in flight) also keep the last good catalog instead of the raw error.
|
Claude finished @KartikSuthar's task in 4m 7s —— View job Claude finished the review (ultracode — from scratch)Todo list
SummaryThis PR adds a backoff/dedup wrapper ( Both issues from the previous review round are now fixed:
This round's deep diveI re-traced the whole mechanism end-to-end (wrapper installation idempotency, the "in-progress" placeholder dedup, rate-limit gating, backoff clamping, stale-catalog fallback, cache invalidation on license change) plus the two small call sites, and used independent agents to adversarially verify two candidate concerns before reporting them:
No other correctness, race-condition, or caching-invariant bugs found. The design holds up: idempotent wrapper installation, bounded self-healing "in progress" placeholder (2 min), rate-limit-aware backoff clamped 5 min–1 hour, and stale-catalog fallback applied consistently across all three return paths (cached-error, rate-limited, and live-failure). The Remaining caveats (unchanged from last round, still can't be resolved in this environment)
VerdictBoth prior findings are fixed, and this round's deeper adversarial pass didn't surface any new confirmed issues. Looks good to merge from a correctness/security standpoint, pending the standard lint/test run. |
Jira Issue:
https://buddyboss.atlassian.net/browse/PROD-10283
General Note
Keep all conversations related to this PR in the associated Jira issue(s). Do NOT add comment on this PR or edit this PR’s description.
Notes to Developer
Notes to Reviewer