Capacitor Plugin Bridge Timeout Configuration Lacking Per‑Plugin Override
0 reputation · 26 Aug 2022, 05:14 UTC
0 reputation · 26 Aug 2022, 05:14 UTC
The Capacitor JavaScript‑to‑native bridge serializes arguments and return values and uses a hardcoded timeout when awaiting native plugin responses. Developers sometimes need a specific plugin call to wait longer (or shorter) than the default without changing the global timeout that affects all plugins.
Currently the bridge implementation does not expose a way to pass a timeout value through plugin options or Capacitor configuration, and it is unclear whether native‑side overrides can be applied selectively for a single plugin method.
What mechanisms, if any, exist to specify a timeout on a per‑plugin basis? Can the bridge timeout be adjusted globally without modifying Capacitor source, and does the API allow overriding the default timeout for individual plugin invocations?
33775 reputation · 26 Aug 2022, 17:11 UTC
The Capacitor JavaScript-to-native bridge does not currently provide a native mechanism to specify timeouts on a per-plugin or per-invocation basis. The bridge is designed as an asynchronous request-response system where the JavaScript Promise remains pending until the native side explicitly invokes a success or error callback.
Based on the current architecture of the Capacitor core (iOS and Android), the following constraints apply:
capacitor.config.ts plugin configuration map does not support a bridge-level timeout key. Configuration passed here is delivered to the plugin's native initialization, not the bridge's transport layer.Plugin.method({ options }) signature does not include a reserved field for bridge timeouts that the core bridge recognizes.Since the bridge does not support native timeouts, the standard resolution is to implement a timeout wrapper at the JavaScript layer. This ensures the application remains responsive even if a native plugin fails to return a result.
async function withTimeout(promise, ms) {
const timeout = new Promise((_, reject) =>
setTimeout(() => reject(new Error(`Plugin call timed out after ${ms}ms`)), ms)
);
return Promise.race([promise, timeout]);
}
Usage:
try {
const result = await withTimeout(MyPlugin.longRunningTask(), 10000);
} catch (e) {
console.error(e.message);
}
To determine if your specific Capacitor version has a hardcoded timeout or remains pending indefinitely, you can perform the following test:
call.resolve() or call.reject().Diagnostic Detail Needed: Please specify the Capacitor version (e.g., v5.x, v6.x) and the target platform (iOS/Android), as bridge behavior can vary slightly between major version releases.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.