React-native-code-push: com.microsoft.codepush.react.CodePushMalformedDataException Unable to parse contents of [..]/codepush.json

Created on 18 Jan 2018  路  14Comments  路  Source: microsoft/react-native-code-push

Hi,

this is the crash report I've got from crash-analytics service. I wasn't able to reproduce it myself however whatever happens the codepush should not crash, it should safely fallback to original bundle if error happened during it's initialization.

Expected Behavior

CodePush should not crash the app. It should safely fallback to original bundle.

Actual Behavior

App crashes.

java.lang.RuntimeException An error occurred while executing doInBackground() 
    AsyncTask.java:318 android.os.AsyncTask$3.done
    FutureTask.java:354 java.util.concurrent.FutureTask.finishCompletion
    FutureTask.java:223 java.util.concurrent.FutureTask.setException
    FutureTask.java:242 java.util.concurrent.FutureTask.run
    ThreadPoolExecutor.java:1133 java.util.concurrent.ThreadPoolExecutor.runWorker
    ThreadPoolExecutor.java:607 java.util.concurrent.ThreadPoolExecutor$Worker.run
    Thread.java:761 java.lang.Thread.run


Caused by: com.microsoft.codepush.react.CodePushMalformedDataException Unable to parse contents of /data/user/0/my.package.name/files/CodePush/codepush.json, the file may be corrupted. 
    CodePushUtils.java:198 com.microsoft.codepush.react.CodePushUtils.getJsonObjectFromFile
    CodePushUpdateManager.java:55 com.microsoft.codepush.react.CodePushUpdateManager.getCurrentPackageInfo
    CodePushUpdateManager.java:105 com.microsoft.codepush.react.CodePushUpdateManager.getCurrentPackageHash
    CodePushUpdateManager.java:115 com.microsoft.codepush.react.CodePushUpdateManager.getCurrentPackage
    CodePushNativeModule.java:295 com.microsoft.codepush.react.CodePushNativeModule$4.doInBackground
    CodePushNativeModule.java:292 com.microsoft.codepush.react.CodePushNativeModule$4.doInBackground
    AsyncTask.java:304 android.os.AsyncTask$2.call
    FutureTask.java:237 java.util.concurrent.FutureTask.run
    ThreadPoolExecutor.java:1133 java.util.concurrent.ThreadPoolExecutor.runWorker
    ThreadPoolExecutor.java:607 java.util.concurrent.ThreadPoolExecutor$Worker.run
    Thread.java:761 java.lang.Thread.run


Caused by: org.json.JSONException End of input at character 0 of  
    JSONTokener.java:449 org.json.JSONTokener.syntaxError
    JSONTokener.java:97 org.json.JSONTokener.nextValue
    JSONObject.java:156 org.json.JSONObject.<init>
    JSONObject.java:173 org.json.JSONObject.<init>
    CodePushUtils.java:195 com.microsoft.codepush.react.CodePushUtils.getJsonObjectFromFile
    CodePushUpdateManager.java:55 com.microsoft.codepush.react.CodePushUpdateManager.getCurrentPackageInfo
    CodePushUpdateManager.java:105 com.microsoft.codepush.react.CodePushUpdateManager.getCurrentPackageHash
    CodePushUpdateManager.java:115 com.microsoft.codepush.react.CodePushUpdateManager.getCurrentPackage
    CodePushNativeModule.java:295 com.microsoft.codepush.react.CodePushNativeModule$4.doInBackground
    CodePushNativeModule.java:292 com.microsoft.codepush.react.CodePushNativeModule$4.doInBackground
    AsyncTask.java:304 android.os.AsyncTask$2.call
    FutureTask.java:237 java.util.concurrent.FutureTask.run
    ThreadPoolExecutor.java:1133 java.util.concurrent.ThreadPoolExecutor.runWorker
    ThreadPoolExecutor.java:607 java.util.concurrent.ThreadPoolExecutor$Worker.run
    Thread.java:761 java.lang.Thread.run

Reproducible Demo

  • If you can't reproduce the bug on it, provide us as much info as possible about your project

I do have this
apply from: "../../node_modules/react-native-code-push/android/codepush.gradle" line in build.gradle

Environment

  • react-native-code-push version: 5.2.1
  • react-native version: 0.50.3
  • iOS/Android/Windows version: android 7.0
  • Does this reproduce on a debug build or release build?
  • Does this reproduce on a simulator, or only on a physical device?
    Happened dozen of times on release build on physical device.
android enhancement fix-in-master

Most helpful comment

Hi everyone!
We've fixed the issue in the new version of react-native-code-push (5.6.0).

I'll close the issue for now, but feel free to ask any questions or reopen this issue if needed!

All 14 comments

Hi @maxkomarychev, thanks for reaching us.

CodePush should not crash the app. It should safely fallback to original bundle.

Absolutely agreed, to have good UX we definitely should not crash an app while installing broken CodePush update. Currently, we are actively working on CodePush native SDKs (both Android and Apple) migration to the App Center native SDKs, while migrating we are going to fix such kind of problems in addition to general rollbacks enhancement (add an ability to see the reason of rollbacks). The migration process will take some time and when we have it finished - you'll be able to use appcenter-codepush service from the https://github.com/Microsoft/AppCenter-SDK-React-Native/ with all the improvements I've listed above.

Please also let me know if you see any other issues or have any questions.

thanks! do you have any ETA/roadmap on when those new SDKs will be available?

We have this issue reported in our app too both in Sentry and Crashlytics, and likewise haven't been able to reproduce it ourselves.

Our current 7-day metrics for this crash indicate that out of our about 2k weekly active users, 40 users see this crash every week (they're not the same week after week BTW), so roughly 2% of our userbase is affected. It is not a major issue for us, but it is also not rare enough that it doesn't produce some discomfort.

We don't know what the root cause is, but are considering working on a fix to at least prevent CodePush from crashing the app when this happens.

Seeing this on a production app as well. As suggested before, CodePush should probably fallback to the original bundle rather than crashing.

Im getting this as well. please fix!

Also happening here, however it seems to only occur in a specific device (Twist S520).

Positivo Twist (S520), Android 6.0
java.lang.RuntimeException: 
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2583)
  at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2665)
  at android.app.ActivityThread.-wrap11 (ActivityThread.java)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1499)
  at android.os.Handler.dispatchMessage (Handler.java:111)
  at android.os.Looper.loop (Looper.java:207)
  at android.app.ActivityThread.main (ActivityThread.java:5765)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:789)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:679)
Caused by: com.microsoft.codepush.react.CodePushMalformedDataException: 
  at com.microsoft.codepush.react.CodePushUtils.getJsonObjectFromFile (CodePushUtils.java:198)
  at com.microsoft.codepush.react.CodePushUpdateManager.getCurrentPackageInfo (CodePushUpdateManager.java:55)
  at com.microsoft.codepush.react.CodePushUpdateManager.getCurrentPackageHash (CodePushUpdateManager.java:105)
  at com.microsoft.codepush.react.CodePushUpdateManager.getCurrentPackage (CodePushUpdateManager.java:115)
  at com.microsoft.codepush.react.CodePush.initializeUpdateAfterRestart (CodePush.java:254)
  at com.microsoft.codepush.react.CodePush.<init> (CodePush.java:82)
  at com.educarebox.app.MainApplication$1.getPackages (MainApplication.java:47)
  at com.facebook.react.ReactNativeHost.createReactInstanceManager (ReactNativeHost.java:81)
  at com.facebook.react.ReactNativeHost.getReactInstanceManager (ReactNativeHost.java:45)
  at com.facebook.react.ReactActivityDelegate.loadApp (ReactActivityDelegate.java:88)
  at com.facebook.react.ReactActivityDelegate.onCreate (ReactActivityDelegate.java:77)
  at com.facebook.react.ReactActivity.onCreate (ReactActivity.java:54)
  at android.app.Activity.performCreate (Activity.java:6301)
  at android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1113)
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2530)
Caused by: org.json.JSONException: 
  at org.json.JSONTokener.syntaxError (JSONTokener.java:449)
  at org.json.JSONTokener.nextValue (JSONTokener.java:97)
  at org.json.JSONObject.<init> (JSONObject.java:156)
  at org.json.JSONObject.<init> (JSONObject.java:173)
  at com.microsoft.codepush.react.CodePushUtils.getJsonObjectFromFile (CodePushUtils.java:195)

We also see this on Samsung Galaxy S9 and Sony Xperia X compact

@yuri-kulikov any update on this issue...approximately 5% of users face this issue

This really bugs people here, which make CodePush is unusable on any production environment, yet the migration to AppCenter already took one year and we haven't seen any glance of a trace of CodePush being migrated, looks like CodePush has been overlooked for a while.

Anyway, we've made a workaround for this unrecoverable fatal error here, the whole idea is to mimic the behavior of CodePush.clearUpdates() and remove all corrupted files so you can create a CodePush instance safely later.

In your MainApplication.java or whever you manage ReactNativeInstance,

@Override
protected List<ReactPackage> getPackages() {

  CodePush codePush;

  try {
      codePush = new CodePush(BuildConfig.CODEPUSH_KEY, getApplicationContext(), BuildConfig.DEBUG);
  } catch (Exception e) {
      // Reset code push update files when update files corrupted.
      // The following code is a mimic of CodePush.clearUpdates()
      // Since we already has exception in CodePush constructor,
      // we breakdown the constructor here and clear all code push
      // related files step by step without read the corrupted file itself.
      Context mContext = getApplicationContext();
      CodePushUpdateManager mUpdateManager = new CodePushUpdateManager(mContext.getFilesDir().getAbsolutePath());
      SettingsManager mSettingsManager = new SettingsManager(mContext);
      mUpdateManager.clearUpdates();
      mSettingsManager.removeFailedUpdates();
      mSettingsManager.removePendingUpdate();
      // After code push update files being removed, we can build a new code push instance safely
      codePush = new CodePush(BuildConfig.CODEPUSH_KEY, getApplicationContext(), BuildConfig.DEBUG);      
  }  
  return Arrays.<ReactPackage>asList(      
    codePush
    //...your other react native packages
  );
}

If you are a careful person, you might need a way to reproduce this exception, the easiest way to do this is upload a 0 bytes codepush.json into /data/data/<your app package name>/files/CodePush via Android Studio or adb on a CodePushed device and you will see this crash when you launch that app, once you applied the workaround above, the corrupted file shall be removed after launch and the whole CodePush update flow will be triggered again since all file has been removed.

Hi @eggli,
Thanks for the workaround, we appreciate it!

We'll try to reproduce it as you recommended and try to create a workaround in our package until we find out why codepush.json can become empty.

@eggli thanks for the workaround. We will try this solution

Hi @eggli,
Thanks for the workaround, we appreciate it!

We'll try to reproduce it as you recommended and try to create a workaround in our package until we find out why codepush.json can become empty.

I've checked codes that read/writes codepush.json, basically, I don't see anything wrong there, but in the world of Android, there're tons of hardware and OS pitfalls everywhere, in a summary, never trust your device, we are seeing this exception on some decent device like Samsung Galaxy S8+ aswell, it's very hard to figure out what's the root cause, yet we can make an assumption that users might kill the app during the writing process, it's a very common user behavior since people DO wrongly opened the app and killed it right away and the codepush.json might become empty.

Yet personally I've reproduced this empty file situation sometimes with this method, but it's not 100% reproducible.

@eggli, thanks for sharing this information with us. I tried to reproduce this bug but wasn't lucky enough.

Work on a fix is in progress.

Hi everyone!
We've fixed the issue in the new version of react-native-code-push (5.6.0).

I'll close the issue for now, but feel free to ask any questions or reopen this issue if needed!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Phredward picture Phredward  路  3Comments

ACCTFORGH picture ACCTFORGH  路  3Comments

diegocouto picture diegocouto  路  4Comments

panarasi picture panarasi  路  4Comments

EdmundMai picture EdmundMai  路  4Comments