fix(android): reject JS promise when plugin invoke fails with PluginLoadException or InvalidPluginMethodException - #8581
Open
xia-chao wants to merge 1 commit into
Conversation
…oadException or InvalidPluginMethodException When PluginHandle.invoke() throws PluginLoadException or InvalidPluginMethodException inside the taskHandler runnable, only Logger.error was called and call.errorCallback() was skipped, so the JS-side promise never settled and awaited calls hung forever. Align this path with the existing error paths (plugin not found, outer catch) by calling call.errorCallback(ex.getMessage()).
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.
Problem
When
PluginHandle.invoke()throwsPluginLoadExceptionorInvalidPluginMethodExceptioninside thetaskHandlerrunnable inBridge.callPluginMethod(), the catch block only callsLogger.error(...)and never callscall.errorCallback(...):As a result, the JS-side promise returned by
Capacitor.Plugins.*.method()never settles — the callerawaits forever with no error. A typical trigger is a typo'd method name on an existing plugin (e.g.await Plugins.App.getInfoTypo()), which throwsInvalidPluginMethodExceptionnatively but leaves the JS promise pending forever.The two neighboring error paths already reject the JS call:
call.errorCallback(...)(Bridge.java~L822)catch (Exception ex)→call.errorCallback(ex.toString())(~L858)Only the two invoke exceptions inside the runnable were missing the callback, so the promise hung instead of rejecting.
Fix
Call
call.errorCallback(ex.getMessage())in thePluginLoadException | InvalidPluginMethodExceptioncatch block, aligning it with the existing error paths. The error message now propagates to JS and the promise rejects.Testing
Added
BridgeCallPluginMethodTest(JUnit 4, Mockito) covering both exception types:invalidPluginMethodCallsErrorCallback— plugin exists, method name is invalid → verifieserrorCallbackis invoked with a message containing the method namepluginLoadExceptionCallsErrorCallback— plugin fails to load → verifieserrorCallbackis invoked with the load-failure messageFull unit suite passes (
./gradlew -b capacitor/build.gradle testDebugUnitTest, 50/50, including the new tests).