Skip to content

Commit ad5bb01

Browse files
authored
Report download failures, add more fields to report (#36)
1 parent edd2d36 commit ad5bb01

5 files changed

Lines changed: 53 additions & 14 deletions

File tree

code-push-plugin-testing-framework/script/serverUtil.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ function setupServer(targetPlatform) {
3131
console.log("Application downloading the package.");
3232
res.download(exports.updatePackagePath);
3333
});
34+
app.post("/v0.1/public/codepush/report_status/download", function (req, res) {
35+
console.log("Application reported download status.");
36+
console.log("Body: " + JSON.stringify(req.body));
37+
res.sendStatus(200);
38+
});
3439
app.post("/reportTestMessage", function (req, res) {
3540
console.log("Application reported a test message.");
3641
console.log("Body: " + JSON.stringify(req.body));

package-mixins.js

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { NativeEventEmitter } from "react-native";
22
import log from "./logging";
3+
import { DownloadStatus } from "./lib/acquisition-sdk/acquisition-sdk";
34

45
// Reporting this event is important, but avoid blocking install()/restartApp() indefinitely
56
// on a stalled network request.
@@ -39,22 +40,35 @@ module.exports = (NativeCodePush) => {
3940
);
4041
}
4142

43+
const downloadStartTime = Date.now();
44+
const reportDownloadStatus = async (status) => {
45+
if (!reportStatusDownload) return;
46+
// Only report a duration on success: on failure, this would be the time until
47+
// the download broke rather than a completed download's duration, and could be misleading.
48+
const downloadDurationMs = status === DownloadStatus.Succeeded ? Date.now() - downloadStartTime : undefined;
49+
try {
50+
await withTimeout(reportStatusDownload({ ...this, downloadDurationMs, status }), REPORT_STATUS_DOWNLOAD_TIMEOUT_MS);
51+
} catch (err) {
52+
log(`Report download status failed: ${err}`);
53+
}
54+
};
55+
4256
// Use the downloaded package info. Native code will save the package info
4357
// so that the client knows what the current package version is.
4458
try {
4559
const updatePackageCopy = Object.assign({}, this);
4660
Object.keys(updatePackageCopy).forEach((key) => (typeof updatePackageCopy[key] === 'function') && delete updatePackageCopy[key]);
4761

48-
const downloadedPackage = await NativeCodePush.downloadUpdate(updatePackageCopy, !!downloadProgressCallback);
49-
50-
if (reportStatusDownload) {
51-
try {
52-
await withTimeout(reportStatusDownload(this), REPORT_STATUS_DOWNLOAD_TIMEOUT_MS);
53-
} catch (err) {
54-
log(`Report download status failed: ${err}`);
55-
}
62+
let downloadedPackage;
63+
try {
64+
downloadedPackage = await NativeCodePush.downloadUpdate(updatePackageCopy, !!downloadProgressCallback);
65+
} catch (err) {
66+
await reportDownloadStatus(DownloadStatus.Failed);
67+
throw err;
5668
}
5769

70+
await reportDownloadStatus(DownloadStatus.Succeeded);
71+
5872
return { ...downloadedPackage, ...local };
5973
} finally {
6074
downloadProgressSubscription && downloadProgressSubscription.remove();

src/acquisition-sdk/__tests__/acquisition-sdk.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ describe("Acquisition SDK", () => {
222222
it("reportStatusDownload(...) signals completion", (done: Mocha.Done): void => {
223223
var acquisition = new acquisitionSdk.AcquisitionManager(new mockApi.HttpRequester(), configuration);
224224

225-
acquisition.reportStatusDownload(templateCurrentPackage, ((error: Error, parameter: void): void => {
225+
acquisition.reportStatusDownload({ ...templateCurrentPackage, status: acquisitionSdk.DownloadStatus.Succeeded }, ((error: Error, parameter: void): void => {
226226
if (error) {
227227
throw error;
228228
}
@@ -261,7 +261,7 @@ describe("Acquisition SDK", () => {
261261
(acquisitionSdk.AcquisitionManager as any)._apiCallsDisabled = false;
262262
}));
263263

264-
acquisition.reportStatusDownload(templateCurrentPackage, ((error: Error, parameter: void): void => {
264+
acquisition.reportStatusDownload({ ...templateCurrentPackage, status: acquisitionSdk.DownloadStatus.Succeeded }, ((error: Error, parameter: void): void => {
265265
assert.strictEqual((acquisitionSdk.AcquisitionManager as any)._apiCallsDisabled, true);
266266
acquisition = acquisition = new acquisitionSdk.AcquisitionManager(new mockApi.CustomResponseHttpRequester(invalidJsonResponse), configuration);
267267
(acquisitionSdk.AcquisitionManager as any)._apiCallsDisabled = false;
@@ -287,7 +287,7 @@ describe("Acquisition SDK", () => {
287287
assert.strictEqual((acquisitionSdk.AcquisitionManager as any)._apiCallsDisabled, false);
288288
}));
289289

290-
acquisition.reportStatusDownload(templateCurrentPackage, ((error: Error, parameter: void): void => {
290+
acquisition.reportStatusDownload({ ...templateCurrentPackage, status: acquisitionSdk.DownloadStatus.Succeeded }, ((error: Error, parameter: void): void => {
291291
assert.strictEqual((acquisitionSdk.AcquisitionManager as any)._apiCallsDisabled, false);
292292
}));
293293

src/acquisition-sdk/acquisition-sdk.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Vendored from https://github.com/microsoft/code-push/blob/master/src/script/acquisition-sdk.ts (archived, MIT licensed)
22

3-
import { UpdateCheckResponse, UpdateCheckRequest, DeploymentStatusReport, DownloadReport } from "./types";
3+
import { UpdateCheckResponse, UpdateCheckRequest, DeploymentStatusReport, DownloadReport, DownloadStatusValue } from "./types";
44
import { CodePushHttpError, CodePushDeployStatusError, CodePushPackageError } from "./code-push-error"
55

66
export namespace Http {
@@ -35,6 +35,11 @@ export interface RemotePackage extends Package {
3535
downloadUrl: string;
3636
}
3737

38+
export interface DownloadedPackage extends Package {
39+
downloadDurationMs?: number;
40+
status: DownloadStatusValue;
41+
}
42+
3843
export interface NativeUpdateNotification {
3944
updateAppVersion: boolean; // Always true
4045
appVersion: string;
@@ -59,6 +64,11 @@ export class AcquisitionStatus {
5964
public static DeploymentFailed = "DeploymentFailed";
6065
}
6166

67+
export class DownloadStatus {
68+
public static Succeeded: DownloadStatusValue = "DownloadSucceeded";
69+
public static Failed: DownloadStatusValue = "DownloadFailed";
70+
}
71+
6272
export class AcquisitionManager {
6373
private readonly BASE_URL_PART = "appcenter.ms";
6474
private _appVersion: string;
@@ -235,7 +245,7 @@ export class AcquisitionManager {
235245
});
236246
}
237247

238-
public reportStatusDownload(downloadedPackage: Package, callback?: Callback<void>): void {
248+
public reportStatusDownload(downloadedPackage: DownloadedPackage, callback?: Callback<void>): void {
239249
if (AcquisitionManager._apiCallsDisabled) {
240250
console.log(`[CodePush] Api calls are disabled, skipping API call`);
241251
callback(/*error*/ null, /*not used*/ null);
@@ -246,7 +256,11 @@ export class AcquisitionManager {
246256
var body: DownloadReport = {
247257
client_unique_id: this._clientUniqueId,
248258
deployment_key: this._deploymentKey,
249-
label: downloadedPackage.label
259+
label: downloadedPackage.label,
260+
package_hash: downloadedPackage.packageHash,
261+
package_size_bytes: downloadedPackage.packageSize,
262+
download_duration_ms: downloadedPackage.downloadDurationMs,
263+
status: downloadedPackage.status
250264
};
251265

252266
this._httpRequester.request(Http.Verb.POST, url, JSON.stringify(body), (error: Error, response: Http.Response): void => {

src/acquisition-sdk/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,17 @@ export interface DeploymentStatusReport {
1313
status?: string;
1414
}
1515

16+
export type DownloadStatusValue = "DownloadSucceeded" | "DownloadFailed";
17+
1618
/*in*/
1719
export interface DownloadReport {
1820
client_unique_id: string;
1921
deployment_key: string;
2022
label: string;
23+
package_hash: string;
24+
package_size_bytes: number;
25+
download_duration_ms?: number;
26+
status: DownloadStatusValue;
2127
}
2228

2329
/*out*/

0 commit comments

Comments
 (0)