Repository navigation
Retry a failed notifyAppReady() on the next call - #106
Merged
Merged
Conversation
CodePush.js cached the promise of the first notifyAppReady() call, even when it rejected. After a failure, every later notifyAppReady() and sync() call failed the same way until the app restarted, and the update was rolled back. The cache now keeps a pending or resolved promise only, so the next caller tries again. A caller that ignores the promise still gets the unhandled rejection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues remain for the change allowing notifyApplicationReady() to retry after a rejected attempt.
No open issues 🎉
What changed in this PR
Fixes permanently cached failures in notifyApplicationReady(), allowing a later call to retry instead of leaving a healthy update vulnerable to rollback.
Changes:
- Adds a TypeScript helper that clears rejected attempts while sharing pending calls and caching success.
- Applies the helper to
notifyApplicationReady()without changing rejection propagation. - Adds unit tests for deduplication, retry after rejection, and success caching.
| File | Description |
|---|---|
src/once-until-rejected.ts |
Implements promise caching that resets after rejection. |
src/__tests__/once-until-rejected.test.ts |
Tests shared pending calls, retries, and cached success. |
CodePush.js |
Replaces permanent promise caching with the new helper. |
Review effort: Balanced
Merged
gsanta
approved these changes
Nov 4, 2026
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.
Background
notifyApplicationReady()is how the app tells CodePush that a freshly installed bundle booted fine. If native code doesn't hear it before the next launch, it assumes the update is broken and rolls it back.sync()also calls it first, before checking for updates.The JS side memoized that call so native code is only asked once per app session. It memoized the promise, whatever the outcome.
Problem
If the native call fails once, for example on a transient bridge error at startup, the rejected promise stays cached. From then on:
sync()in that session fails immediately and never checks for updates.Change
Keep the memoization, but drop a rejected promise so the next caller tries again. Concurrent callers still share one in-flight call, and a success is still cached for the session. The helper is in
src/with unit tests, per the rule for new code.Not covered
An app that calls
notifyApplicationReady()once at startup and ignores the error still never retries. Only callers likesync()benefit. Having the SDK retry on its own would be a separate decision.🤖 Generated with Claude Code