kiwix / kiwix-android

Kiwix for Android
https://android.kiwix.org
GNU General Public License v3.0
892 stars 448 forks source link

Medical wikimedia (mini) keeps crashing #4000

Closed Popolechien closed 1 month ago

Popolechien commented 1 month ago

At least this time the user provided a log. Should I ask for more info?

logs1726851491827.txt

MohitMaliFtechiz commented 1 month ago

@Popolechien Thanks for the log file, there is enough information in the log file to fix the problem.

kelson42 commented 1 month ago

@MohitMaliFtechiz For this issue, il would request:

MohitMaliFtechiz commented 1 month ago

@kelson42 The issue is related to the file system. We are using the ContextCompat.getExternalFilesDirs() function to retrieve the file directories for our application's storage. However, this function can return null when the file system (e.g., an SD card) is unavailable.

Screenshot from 2024-09-23 17-56-38

This issue occurred when we tried to access ZIM files from the application’s folder in the zimFiles() method. In this method, we add directories to a non-null list of files. However, when attempting to retrieve the list of files from the application directory, the SD card path was null due to the SD card being unmounted, which caused the application to crash.

java.lang.NullPointerException: dir must not be null
at org.kiwix.kiwixmobile.custom.main.CustomFileValidator.zimFiles(CustomFileValidator.kt:46)
at org.kiwix.kiwixmobile.custom.main.CustomReaderFragment.openObbOrZim(CustomReaderFragment.kt:30)
at org.kiwix.kiwixmobile.custom.main.CustomReaderFragment.onViewCreated(CustomReaderFragment.kt:204)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:254)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:146)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:58)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:34)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:259)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:146)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:58)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:34)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:32)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:1)
at org.kiwix.kiwixmobile.core.main.CoreMainActivity.onStart(CoreMainActivity.kt:1)
at org.kiwix.kiwixmobile.custom.main.CustomMainActivity.onStart(CustomMainActivity.kt:1)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1510)
at android.app.Activity.performStart(Activity.java:8616)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:4204)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2574)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8762)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)

Quantitative impact estimation over all our apps

This is a specific edge case that only occurs when an SD card is unmounted while the application is running. It will not affect all users; only those who unmount their SD card while the application is trying to access the directory will experience this issue.

Automated test to avoid late detection in the future

Sure, i am writing test cases for this.

kelson42 commented 1 month ago

@MohitMaliFtechiz Thank you for the explanation. Before we talk about appropriate error handling. Can you please tell me how the user can save an app on their SD card?

MohitMaliFtechiz commented 1 month ago

@MohitMaliFtechiz Thank you for the explanation. Before we talk about appropriate error handling. Can you please tell me how the user can save an app on their SD card?

@kelson42 The application itself is not saved on the SD card. In custom apps, we store ZIM files as expansion files in the OBB folder. We have a fallback system in place: if the ZIM file is not present, the user can download it via the custom app's download page. The ZIM file is then downloaded to the storage location with the most available space, as per our logic. If the SD card has more available space than internal storage, the ZIM file will be downloaded to the SD card. To account for this, we scan both internal and external storage using methods like obbFiles, and zimFiles

In this crash scenario, the application crashed while scanning the SD card.

kelson42 commented 1 month ago

@MohitMaliFtechiz Thank you again for the explanation. To me - as it is - it seems to be too much of hack. Do you remember exactly or could investigate which issue justified the implementation of this feature?

MohitMaliFtechiz commented 1 month ago

@kelson42 This feature was introduced here https://github.com/kiwix/kiwix-android/pull/1580 for this issue https://github.com/kiwix/kiwix-android/issues/64, and the fallback method was proposed here https://github.com/kiwix/kiwix-android/issues/64#issuecomment-548325163.

kelson42 commented 1 month ago

OK, Inbelieve all of this is pretty complex but I'm not bold enough to just remove it (for the moment).