Skip to content

mobile: the App listener's rejection reaches the catch - #408

Open
kurktchiev wants to merge 1 commit into
DuarteSantos8:mainfrom
kurktchiev:gh/mobile-listener-catch
Open

kurktchiev wants to merge 1 commit into
DuarteSantos8:mainfrom
kurktchiev:gh/mobile-listener-catch

Conversation

@kurktchiev

Copy link
Copy Markdown
Contributor

initReminderSync and onAppActive both dropped the promise
App.addListener returns inside a block body:

import('@capacitor/app').then(({ App }) => {
  App.addListener('appStateChange', ({ isActive }) => { if (isActive) resync() })
}).catch(() => {})

When the App plugin isn't behind the bridge (a native project whose Capacitor
cap sync never ran, or a custom platform), addListener rejects
(UNIMPLEMENTED), and since the arrow's block body never returns that
promise, the .catch() right behind it never sees it. Every boot raised an
unhandled rejection.

Both are one-line fixes that return the promise instead of dropping it.

frontend 2 new tests in mobile.listener.test.js, run with npx vitest run --maxWorkers=2. They use a plain rejecting object standing in for the App
plugin rather than a vi.fn, because a spy attaches its own handlers to every
promise it returns, which counts as handling it and would hide this exact
leak. Checked against the old code first (both tests failed, catching the
plugin's rejection message as an unhandled rejection), then against the fix
(both pass). 9 total in the two mobile test files, all passing.

#391 (OIDC sign-in) rewrites onAppActive, and its version already returns
the listener's promise, so the two conflict there. Resolving takes #391's
onAppActive and this PR's initReminderSync change.

🤖 Generated with Claude Code

initReminderSync and onAppActive both dropped the promise
App.addListener returns inside a block body, so when the App plugin is
not behind the bridge (Capacitor's proxy rejects with UNIMPLEMENTED)
the existing .catch never saw it and every boot raised an unhandled
rejection. The arrow returns it now.

Reproduced with a plain rejecting object: a vi.fn cannot, because
vitest attaches its own handlers to every promise a spy returns, which
counts as handling it and would hide exactly this leak.

frontend 2 new tests, run against the old code first to confirm they
fail there (both did, with the plugin's rejection message), then
against the fix (both pass).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
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