diff --git a/package-mixins.js b/package-mixins.js index 18ef439..6df5da5 100644 --- a/package-mixins.js +++ b/package-mixins.js @@ -1,6 +1,23 @@ import { NativeEventEmitter } from "react-native"; import log from "./logging"; +// Reporting this event is important, but avoid blocking install()/restartApp() indefinitely +// on a stalled network request. +const REPORT_STATUS_DOWNLOAD_TIMEOUT_MS = 5000; + +async function withTimeout(promise, timeoutMs) { + let timer; + const timeout = new Promise((_, reject) => { + timer = setTimeout(() => reject(new Error(`Timed out after ${timeoutMs}ms`)), timeoutMs); + }); + + try { + return await Promise.race([promise, timeout]); + } finally { + clearTimeout(timer); + } +} + // This function is used to augment remote and local // package objects with additional functionality/properties // beyond what is included in the metadata sent by the server. @@ -31,10 +48,11 @@ module.exports = (NativeCodePush) => { const downloadedPackage = await NativeCodePush.downloadUpdate(updatePackageCopy, !!downloadProgressCallback); if (reportStatusDownload) { - reportStatusDownload(this) - .catch((err) => { + try { + await withTimeout(reportStatusDownload(this), REPORT_STATUS_DOWNLOAD_TIMEOUT_MS); + } catch (err) { log(`Report download status failed: ${err}`); - }); + } } return { ...downloadedPackage, ...local }; @@ -65,4 +83,4 @@ module.exports = (NativeCodePush) => { }; return { local, remote }; -}; \ No newline at end of file +}; diff --git a/src/acquisition-sdk/acquisition-sdk.ts b/src/acquisition-sdk/acquisition-sdk.ts index 4d5c006..d957d65 100644 --- a/src/acquisition-sdk/acquisition-sdk.ts +++ b/src/acquisition-sdk/acquisition-sdk.ts @@ -166,6 +166,7 @@ export class AcquisitionManager { }); } + // Note: deployedPackage and status are null when reporting a "binary update" (i.e. the app was updated through the app store, not CodePush) public reportStatusDeploy(deployedPackage?: Package, status?: string, previousLabelOrAppVersion?: string, previousDeploymentKey?: string, callback?: Callback): void { if (AcquisitionManager._apiCallsDisabled) { console.log(`[CodePush] Api calls are disabled, skipping API call`); @@ -289,4 +290,4 @@ function queryStringify(object: Object): string { } return queryString; -} \ No newline at end of file +}