Skip to content

Commit 4de04ac

Browse files
ofalvaiclaude
andcommitted
Logging: introduce log levels on JS and Android
- logging.js exports info/warn/error instead of a single log(). warn and error map to console.warn/console.error. error() includes the stack. - Android: new CodePushLog.kt (Log.i/Log.w/Log.e) replaces CodePushUtils.log(). Exception-only call sites now have a context message instead of "[CodePush] Exception". printStackTrace() calls now go through the logger. - iOS: CPLog no longer prepends a newline. The signature verification line uses CPLog, so it has the [CodePush] prefix. - Remove the leftover [MyDebug] line and the untyped CodePush.log export. - "Report status failed" and sync failures now log the error and stack. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent d8637f0 commit 4de04ac

16 files changed

Lines changed: 153 additions & 119 deletions

‎CodePush.js‎

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ async function downloadUpdate(remotePackage, downloadProgressCallback, reportSta
5050
try {
5151
await withTimeout(reportStatusDownload({ ...remotePackage, downloadDurationMs, status }), REPORT_STATUS_DOWNLOAD_TIMEOUT_MS);
5252
} catch (err) {
53-
log(`Report download status failed: ${err}`);
53+
log.warn("Failed to report download status.", err);
5454
}
5555
};
5656

@@ -142,7 +142,7 @@ async function checkForUpdate(deploymentKey = null, handleBinaryVersionMismatchC
142142
localPackage && (update.packageHash === localPackage.packageHash) ||
143143
(!localPackage || localPackage._isDebugOnly) && config.packageHash === update.packageHash) {
144144
if (update && update.updateAppVersion) {
145-
log("An update is available but it is not targeting the binary version of your app.");
145+
log.info("An update is available but it is not targeting the binary version of your app.");
146146
if (handleBinaryVersionMismatchCallback && typeof handleBinaryVersionMismatchCallback === "function") {
147147
handleBinaryVersionMismatchCallback(update)
148148
}
@@ -275,7 +275,7 @@ async function tryReportStatus(statusReport, retryOnAppResume) {
275275
const previousDeploymentKey = statusReport.previousDeploymentKey || config.deploymentKey;
276276
try {
277277
if (statusReport.appVersion) {
278-
log(`Reporting binary update (${statusReport.appVersion})`);
278+
log.info(`Reporting binary update (${statusReport.appVersion})`);
279279

280280
if (!config.deploymentKey) {
281281
throw new Error("Deployment key is missed");
@@ -286,9 +286,9 @@ async function tryReportStatus(statusReport, retryOnAppResume) {
286286
} else {
287287
const label = statusReport.package.label;
288288
if (statusReport.status === "DeploymentSucceeded") {
289-
log(`Reporting CodePush update success (${label})`);
289+
log.info(`Reporting CodePush update success (${label})`);
290290
} else {
291-
log(`Reporting CodePush update rollback (${label})`);
291+
log.info(`Reporting CodePush update rollback (${label})`);
292292
await NativeCodePush.setLatestRollbackInfo(statusReport.package.packageHash);
293293
}
294294

@@ -300,7 +300,7 @@ async function tryReportStatus(statusReport, retryOnAppResume) {
300300
NativeCodePush.recordStatusReported(statusReport);
301301
retryOnAppResume && retryOnAppResume.remove();
302302
} catch (e) {
303-
log(`Report status failed: ${JSON.stringify(statusReport)}`);
303+
log.error(`Report status failed: ${JSON.stringify(statusReport)}`, e);
304304
NativeCodePush.saveStatusReportForRetry(statusReport);
305305
// Try again when the app resumes
306306
if (!retryOnAppResume) {
@@ -341,14 +341,14 @@ async function shouldUpdateBeIgnored(remotePackage, syncOptions) {
341341

342342
const latestRollbackInfo = await NativeCodePush.getLatestRollbackInfo();
343343
if (!validateLatestRollbackInfo(latestRollbackInfo, remotePackage.packageHash)) {
344-
log("The latest rollback info is not valid.");
344+
log.info("The latest rollback info is not valid.");
345345
return true;
346346
}
347347

348348
const { delayInHours, maxRetryAttempts } = rollbackRetryOptions;
349349
const hoursSinceLatestRollback = (Date.now() - latestRollbackInfo.time) / (1000 * 60 * 60);
350350
if (hoursSinceLatestRollback >= delayInHours && maxRetryAttempts >= latestRollbackInfo.count) {
351-
log("Previous rollback should be ignored due to rollback retry options.");
351+
log.info("Previous rollback should be ignored due to rollback retry options.");
352352
return false;
353353
}
354354

@@ -365,17 +365,17 @@ function validateLatestRollbackInfo(latestRollbackInfo, packageHash) {
365365

366366
function validateRollbackRetryOptions(rollbackRetryOptions) {
367367
if (typeof rollbackRetryOptions.delayInHours !== "number") {
368-
log("The 'delayInHours' rollback retry parameter must be a number.");
368+
log.warn("The 'delayInHours' rollback retry parameter must be a number.");
369369
return false;
370370
}
371371

372372
if (typeof rollbackRetryOptions.maxRetryAttempts !== "number") {
373-
log("The 'maxRetryAttempts' rollback retry parameter must be a number.");
373+
log.warn("The 'maxRetryAttempts' rollback retry parameter must be a number.");
374374
return false;
375375
}
376376

377377
if (rollbackRetryOptions.maxRetryAttempts < 1) {
378-
log("The 'maxRetryAttempts' rollback retry parameter cannot be less then 1.");
378+
log.warn("The 'maxRetryAttempts' rollback retry parameter cannot be less then 1.");
379379
return false;
380380
}
381381

@@ -408,7 +408,7 @@ const sync = (() => {
408408
try {
409409
syncStatusChangeCallback(...args);
410410
} catch (error) {
411-
log(`An error has occurred : ${error.stack}`);
411+
log.error("The sync status callback threw an error.", error);
412412
}
413413
}
414414
}
@@ -418,15 +418,15 @@ const sync = (() => {
418418
try {
419419
downloadProgressCallback(...args);
420420
} catch (error) {
421-
log(`An error has occurred: ${error.stack}`);
421+
log.error("The download progress callback threw an error.", error);
422422
}
423423
}
424424
}
425425

426426
if (syncInProgress) {
427427
typeof syncStatusCallbackWithTryCatch === "function"
428428
? syncStatusCallbackWithTryCatch(CodePush.SyncStatus.SYNC_IN_PROGRESS)
429-
: log("Sync already in progress.");
429+
: log.info("Sync already in progress.");
430430
return Promise.resolve(CodePush.SyncStatus.SYNC_IN_PROGRESS);
431431
}
432432

@@ -467,36 +467,36 @@ async function syncInternal(options = {}, syncStatusChangeCallback, downloadProg
467467
: (syncStatus) => {
468468
switch(syncStatus) {
469469
case CodePush.SyncStatus.CHECKING_FOR_UPDATE:
470-
log("Checking for update.");
470+
log.info("Checking for update.");
471471
break;
472472
case CodePush.SyncStatus.AWAITING_USER_ACTION:
473-
log("Awaiting user action.");
473+
log.info("Awaiting user action.");
474474
break;
475475
case CodePush.SyncStatus.DOWNLOADING_PACKAGE:
476-
log("Downloading package.");
476+
log.info("Downloading package.");
477477
break;
478478
case CodePush.SyncStatus.INSTALLING_UPDATE:
479-
log("Installing update.");
479+
log.info("Installing update.");
480480
break;
481481
case CodePush.SyncStatus.UP_TO_DATE:
482-
log("App is up to date.");
482+
log.info("App is up to date.");
483483
break;
484484
case CodePush.SyncStatus.UPDATE_IGNORED:
485-
log("User cancelled the update.");
485+
log.info("User cancelled the update.");
486486
break;
487487
case CodePush.SyncStatus.UPDATE_INSTALLED:
488488
if (resolvedInstallMode == CodePush.InstallMode.ON_NEXT_RESTART) {
489-
log("Update is installed and will be run on the next app restart.");
489+
log.info("Update is installed and will be run on the next app restart.");
490490
} else if (resolvedInstallMode == CodePush.InstallMode.ON_NEXT_RESUME) {
491491
if (syncOptions.minimumBackgroundDuration > 0) {
492-
log(`Update is installed and will be run after the app has been in the background for at least ${syncOptions.minimumBackgroundDuration} seconds.`);
492+
log.info(`Update is installed and will be run after the app has been in the background for at least ${syncOptions.minimumBackgroundDuration} seconds.`);
493493
} else {
494-
log("Update is installed and will be run when the app next resumes.");
494+
log.info("Update is installed and will be run when the app next resumes.");
495495
}
496496
}
497497
break;
498498
case CodePush.SyncStatus.UNKNOWN_ERROR:
499-
log("An unknown error occurred.");
499+
log.info("An unknown error occurred.");
500500
break;
501501
}
502502
};
@@ -526,7 +526,7 @@ async function syncInternal(options = {}, syncStatusChangeCallback, downloadProg
526526

527527
if (!remotePackage || updateShouldBeIgnored) {
528528
if (updateShouldBeIgnored) {
529-
log("An update is available, but it is being ignored due to having been previously rolled back.");
529+
log.warn("An update is available, but it is being ignored due to having been previously rolled back.");
530530
}
531531

532532
const currentPackage = await CodePush.getCurrentPackage();
@@ -593,7 +593,7 @@ async function syncInternal(options = {}, syncStatusChangeCallback, downloadProg
593593
}
594594
} catch (error) {
595595
syncStatusChangeCallback(CodePush.SyncStatus.UNKNOWN_ERROR);
596-
log(error.message);
596+
log.error("Sync failed.", error);
597597
throw error;
598598
}
599599
};
@@ -696,7 +696,6 @@ if (NativeCodePush) {
696696
getConfiguration,
697697
getCurrentPackage,
698698
getUpdateMetadata,
699-
log,
700699
notifyAppReady: notifyApplicationReady,
701700
notifyApplicationReady,
702701
restartApp,
@@ -754,7 +753,7 @@ if (NativeCodePush) {
754753
}
755754
});
756755
} else {
757-
log("The CodePush module doesn't appear to be properly installed. Please double-check that everything is setup correctly.");
756+
log.error("The CodePush module doesn't appear to be properly installed. Please double-check that everything is setup correctly.");
758757
}
759758

760759
module.exports = CodePush;

‎android/app/src/main/java/com/microsoft/codepush/react/CodePush.java‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ private String getCustomPropertyFromStringsIfExist(String propertyName) {
151151
if (!property.isEmpty()) {
152152
return property;
153153
} else {
154-
CodePushUtils.log("Specified " + propertyName + " is empty");
154+
CodePushLog.warn("Specified " + propertyName + " is empty");
155155
}
156156
}
157157

@@ -257,20 +257,20 @@ public String getJSBundleFileInternal(String assetsBundleFileName) {
257257
packageFilePath = mUpdateManager.getCurrentPackageBundlePath(this.mAssetsBundleFileName);
258258
} catch (CodePushMalformedDataException e) {
259259
// We need to recover the app in case 'codepush.json' is corrupted
260-
CodePushUtils.log(e);
260+
CodePushLog.error("Failed to read the current package metadata, clearing updates", e);
261261
clearUpdates();
262262
}
263263

264264
if (packageFilePath == null) {
265265
// There has not been any downloaded updates.
266-
CodePushUtils.logBundleUrl(binaryJsBundleUrl);
266+
CodePushLog.info("Loading JS bundle from \"" + binaryJsBundleUrl + "\"");
267267
sIsRunningBinaryVersion = true;
268268
return binaryJsBundleUrl;
269269
}
270270

271271
JSONObject packageMetadata = this.mUpdateManager.getCurrentPackage();
272272
if (isPackageBundleLatest(packageMetadata)) {
273-
CodePushUtils.logBundleUrl(packageFilePath);
273+
CodePushLog.info("Loading JS bundle from \"" + packageFilePath + "\"");
274274
sIsRunningBinaryVersion = false;
275275
return packageFilePath;
276276
} else {
@@ -280,7 +280,7 @@ public String getJSBundleFileInternal(String assetsBundleFileName) {
280280
this.clearUpdates();
281281
}
282282

283-
CodePushUtils.logBundleUrl(binaryJsBundleUrl);
283+
CodePushLog.info("Loading JS bundle from \"" + binaryJsBundleUrl + "\"");
284284
sIsRunningBinaryVersion = true;
285285
return binaryJsBundleUrl;
286286
}
@@ -307,12 +307,12 @@ void initializeUpdateAfterRestart() {
307307
packageMetadata = this.mUpdateManager.getCurrentPackage();
308308
} catch (CodePushMalformedDataException e) {
309309
// We need to recover the app in case 'codepush.json' is corrupted
310-
CodePushUtils.log(e);
310+
CodePushLog.error("Failed to read the current package metadata, clearing updates", e);
311311
clearUpdates();
312312
return;
313313
}
314314
if (packageMetadata == null || !isPackageBundleLatest(packageMetadata) && hasBinaryVersionChanged(packageMetadata)) {
315-
CodePushUtils.log("Skipping initializeUpdateAfterRestart(), binary version is newer");
315+
CodePushLog.info("Skipping initializeUpdateAfterRestart(), binary version is newer");
316316
return;
317317
}
318318

@@ -321,7 +321,7 @@ void initializeUpdateAfterRestart() {
321321
if (updateIsLoading) {
322322
// Pending update was initialized, but notifyApplicationReady was not called.
323323
// Therefore, deduce that it is a broken update and rollback.
324-
CodePushUtils.log("Update did not finish loading the last time, rolling back to a previous version.");
324+
CodePushLog.warn("Update did not finish loading the last time, rolling back to a previous version.");
325325
sNeedToReportRollback = true;
326326
rollbackPackage();
327327
} else {

‎android/app/src/main/java/com/microsoft/codepush/react/CodePushDialog.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public void onClick(DialogInterface dialog, int which) {
7070
throw new CodePushUnknownException("Unknown button ID pressed.");
7171
}
7272
} catch (Throwable e) {
73-
CodePushUtils.log(e);
73+
CodePushLog.error("Failed to handle the update dialog button press", e);
7474
}
7575
}
7676
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.microsoft.codepush.react
2+
3+
import android.util.Log
4+
5+
// Uses the "ReactNative" logcat tag and the [CodePush] prefix, so that native lines show up next to
6+
// React Native's own lines, and a single grep for "[CodePush]" finds both native and JS lines.
7+
object CodePushLog {
8+
private const val PREFIX = "[CodePush] "
9+
10+
@JvmStatic
11+
fun info(message: String) {
12+
Log.i(CodePushConstants.REACT_NATIVE_LOG_TAG, PREFIX + message)
13+
}
14+
15+
@JvmStatic
16+
@JvmOverloads
17+
fun warn(message: String, tr: Throwable? = null) {
18+
Log.w(CodePushConstants.REACT_NATIVE_LOG_TAG, PREFIX + message, tr)
19+
}
20+
21+
@JvmStatic
22+
@JvmOverloads
23+
fun error(message: String, tr: Throwable? = null) {
24+
Log.e(CodePushConstants.REACT_NATIVE_LOG_TAG, PREFIX + message, tr)
25+
}
26+
}

0 commit comments

Comments
 (0)