opensrp / fhircore

FHIR Core / OpenSRP 2 is a Kotlin application for delivering offline-capable, mobile-first healthcare project implementations from local community to national and international scale using FHIR and WHO Smart Guidelines on Android.
https://smartregister.org
Apache License 2.0
53 stars 41 forks source link

Quest v0.2 / G6PD : App crashes when G6PD Test Questionnaire is completed and submitted with a photo attachment #974

Closed f-odhiambo closed 2 years ago

f-odhiambo commented 2 years ago

Describe the bug App crashes when G6PD Test Questionnaire is completed and submitted with a photo attachment

To Reproduce Steps to reproduce the behavior:

  1. Go to the G6PD test
  2. Complete the survey and add a photo/replace photo
  3. Submit a completed test
  4. See error

Expected behavior

  1. Complete questionnaire with photo and submit with no crash
  2. User should be able to update photo before submission and post with no crash

Screenshots See video - TBD

Smartphone (please complete the following information):

Additional context

@f-odhiambo Is this a real device? Does this happens in emulator too? with the same device and API version

FikriMilano commented 2 years ago

@f-odhiambo Is this a real device? Does this happens in emulator too? with the same device and API version

f-odhiambo commented 2 years ago

@f-odhiambo Is this a real device? Does this happen in emulators too? with the same device and API version

Real Devic. See video

https://user-images.githubusercontent.com/4540684/150502386-9e52ec6e-03b4-4aa0-8b8d-06cce138ce99.mp4

FikriMilano commented 2 years ago

Error log:

2022-01-24 16:19:56.591 17400-17400/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: org.smartregister.fhircore.quest, PID: 17400
    java.lang.NoSuchMethodError: No virtual method getParameterCount()I in class Ljava/lang/reflect/Method; or its super classes (declaration of 'java.lang.reflect.Method' appears in /system/framework/core-oj.jar)
        at org.opencds.cqf.cql.engine.data.SystemDataProvider.getWriteAccessor(SystemDataProvider.java:75)
        at org.opencds.cqf.cql.engine.data.SystemDataProvider.setValue(SystemDataProvider.java:117)
        at org.opencds.cqf.cql.engine.execution.Context.setValue(Context.java:857)
        at org.opencds.cqf.cql.engine.elm.execution.InstanceEvaluator.internalEvaluate(InstanceEvaluator.java:12)
        at org.opencds.cqf.cql.engine.elm.execution.Executable.evaluate(Executable.java:18)
        at org.opencds.cqf.cql.engine.elm.execution.IfEvaluator.internalEvaluate(IfEvaluator.java:15)
        at org.opencds.cqf.cql.engine.elm.execution.Executable.evaluate(Executable.java:18)
        at org.opencds.cqf.cql.engine.elm.execution.FunctionRefEvaluator.internalEvaluate(FunctionRefEvaluator.java:33)
        at org.opencds.cqf.cql.engine.elm.execution.Executable.evaluate(Executable.java:18)
        at org.opencds.cqf.cql.engine.elm.execution.EquivalentEvaluator.internalEvaluate(EquivalentEvaluator.java:100)
        at org.opencds.cqf.cql.engine.elm.execution.Executable.evaluate(Executable.java:18)
        at org.opencds.cqf.cql.engine.elm.execution.QueryEvaluator.evaluateWhere(QueryEvaluator.java:75)
        at org.opencds.cqf.cql.engine.elm.execution.QueryEvaluator.internalEvaluate(QueryEvaluator.java:198)
        at org.opencds.cqf.cql.engine.elm.execution.Executable.evaluate(Executable.java:18)
        at org.opencds.cqf.cql.engine.elm.execution.LastEvaluator.internalEvaluate(LastEvaluator.java:30)
        at org.opencds.cqf.cql.engine.elm.execution.Executable.evaluate(Executable.java:18)
        at org.opencds.cqf.cql.engine.elm.execution.ExpressionDefEvaluator.internalEvaluate(ExpressionDefEvaluator.java:19)
        at org.opencds.cqf.cql.engine.elm.execution.Executable.evaluate(Executable.java:18)
        at org.opencds.cqf.cql.engine.execution.CqlEngine.evaluateExpressions(CqlEngine.java:186)
        at org.opencds.cqf.cql.engine.execution.CqlEngine.evaluate(CqlEngine.java:164)
        at org.opencds.cqf.cql.evaluator.CqlEvaluator.evaluate(CqlEvaluator.java:89)
        at org.opencds.cqf.cql.evaluator.library.LibraryEvaluator.evaluate(LibraryEvaluator.java:47)
        at org.smartregister.fhircore.engine.cql.LibraryEvaluator.runCqlLibrary(LibraryEvaluator.kt:230)
        at org.smartregister.fhircore.engine.cql.LibraryEvaluator$runCqlLibrary$1.invokeSuspend(LibraryEvaluator.kt)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at android.os.Handler.handleCallback(Handler.java:836)
        at android.os.Handler.dispatchMessage(Handler.java:103)
        at android.os.Looper.loop(Looper.java:232)
        at android.app.ActivityThread.main(ActivityThread.java:6806)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1103)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)
2022-01-24 16:19:57.472 19107-19107/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: org.smartregister.fhircore.quest, PID: 19107
    java.lang.RuntimeException: Unable to start activity ComponentInfo{org.smartregister.fhircore.quest/org.smartregister.fhircore.quest.ui.patient.register.PatientRegisterActivity}: kotlin.UninitializedPropertyAccessException: lateinit property appId has not been initialized
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2951)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3016)
        at android.app.ActivityThread.-wrap12(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1716)
        at android.os.Handler.dispatchMessage(Handler.java:110)
        at android.os.Looper.loop(Looper.java:232)
        at android.app.ActivityThread.main(ActivityThread.java:6806)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1103)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)
     Caused by: kotlin.UninitializedPropertyAccessException: lateinit property appId has not been initialized
        at org.smartregister.fhircore.engine.configuration.ConfigurationRegistry.getAppId(ConfigurationRegistry.kt:51)
        at org.smartregister.fhircore.engine.configuration.ConfigurationRegistry.workflowPointName(ConfigurationRegistry.kt:145)
        at org.smartregister.fhircore.engine.ui.register.RegisterViewModel.<init>(RegisterViewModel.kt:153)
        at org.smartregister.fhircore.quest.DaggerQuestApplication_HiltComponents_SingletonC$ViewModelCImpl.registerViewModel(DaggerQuestApplication_HiltComponents_SingletonC.java:755)
        at org.smartregister.fhircore.quest.DaggerQuestApplication_HiltComponents_SingletonC$ViewModelCImpl.access$3000(DaggerQuestApplication_HiltComponents_SingletonC.java:700)
        at org.smartregister.fhircore.quest.DaggerQuestApplication_HiltComponents_SingletonC$ViewModelCImpl$SwitchingProvider.get(DaggerQuestApplication_HiltComponents_SingletonC.java:816)
        at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory$1.create(HiltViewModelFactory.java:100)
        at androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:69)
        at androidx.lifecycle.AbstractSavedStateViewModelFactory.create(AbstractSavedStateViewModelFactory.java:84)
        at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:109)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
        at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:54)
        at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:41)
        at org.smartregister.fhircore.engine.ui.register.BaseRegisterActivity.getRegisterViewModel(BaseRegisterActivity.kt:105)
        at org.smartregister.fhircore.engine.ui.register.BaseRegisterActivity.runSync(BaseRegisterActivity.kt:430)
        at org.smartregister.fhircore.engine.sync.SyncBroadcaster.registerSyncInitiator(SyncHandlers.kt:56)
        at org.smartregister.fhircore.engine.ui.register.BaseRegisterActivity.onCreate(BaseRegisterActivity.kt:129)
        at org.smartregister.fhircore.quest.ui.patient.register.PatientRegisterActivity.onCreate(PatientRegisterActivity.kt:40)
        at android.app.Activity.performCreate(Activity.java:6974)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2904)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3016) 
        at android.app.ActivityThread.-wrap12(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1716) 
        at android.os.Handler.dispatchMessage(Handler.java:110) 
        at android.os.Looper.loop(Looper.java:232) 
        at android.app.ActivityThread.main(ActivityThread.java:6806) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1103) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)
FikriMilano commented 2 years ago

I think this crash is related to the recent CQL PR that got merged. Tried to revert and it works. Could you have a look on this @maimoonak?

maimoonak commented 2 years ago

@FikriMilano @f-odhiambo actually it looks like cql-error. But it is actually out of memory error plz see the message after stacktrace

   at java.lang.Throwable.nativeFillInStackTrace(Native method)
   at java.lang.Throwable.fillInStackTrace(Throwable.java:799)
   at java.lang.Throwable.<init>(Throwable.java:277)
   at java.lang.Error.<init>(Error.java:70)
   at java.lang.VirtualMachineError.<init>(VirtualMachineError.java:53)
   at java.lang.OutOfMemoryError.<init>(OutOfMemoryError.java:58)
   at java.util.HashMap.resize(HashMap.java:703)
   at java.util.HashMap.putVal(HashMap.java:662)
   at java.util.HashMap.put(HashMap.java:611)
   at ca.uhn.fhir.context.RuntimeChildChoiceDefinition.sealAndInitialize(RuntimeChildChoiceDefinition.java:156)
   at ca.uhn.fhir.context.RuntimeChildAny.sealAndInitialize(RuntimeChildAny.java:88)
   at ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition.sealAndInitialize(BaseRuntimeElementCompositeDefinition.java:477)
   at ca.uhn.fhir.context.RuntimeResourceDefinition.sealAndInitialize(RuntimeResourceDefinition.java:173)
   at ca.uhn.fhir.context.ModelScanner.init(ModelScanner.java:156)
   at ca.uhn.fhir.context.ModelScanner.<init>(ModelScanner.java:94)
   at ca.uhn.fhir.context.FhirContext.scanResourceTypes(FhirContext.java:998)
   at java.lang.reflect.Method.invoke(Native method)
   at org.opencds.cqf.cql.engine.fhir.model.R4FhirModelResolver.initialize(R4FhirModelResolver.java:95)
   at org.opencds.cqf.cql.engine.fhir.model.FhirModelResolver.<init>(FhirModelResolver.java:56)
   at org.opencds.cqf.cql.engine.fhir.model.R4FhirModelResolver.<init>(R4FhirModelResolver.java:53)
   at org.opencds.cqf.cql.engine.fhir.model.R4FhirModelResolver.<init>(R4FhirModelResolver.java:49)
   at org.smartregister.fhircore.engine.cql.R4FhirModelResolverExt.<init>(R4FhirModelResolverExt.kt:22)
   at org.smartregister.fhircore.engine.cql.LibraryEvaluator$fhirModelResolver$2.invoke(LibraryEvaluator.kt:78)
   at org.smartregister.fhircore.engine.cql.LibraryEvaluator$fhirModelResolver$2.invoke(LibraryEvaluator.kt:78)
   at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
   at org.smartregister.fhircore.engine.cql.LibraryEvaluator.getFhirModelResolver(LibraryEvaluator.kt:78)
   at org.smartregister.fhircore.engine.cql.LibraryEvaluator.loadConfigs(LibraryEvaluator.kt:299)
   at org.smartregister.fhircore.engine.cql.LibraryEvaluator.runCqlLibrary(LibraryEvaluator.kt:221)
   at org.smartregister.fhircore.engine.cql.LibraryEvaluator$runCqlLibrary$1.invokeSuspend(LibraryEvaluator.kt:-1)
   at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
   at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
   at android.os.Handler.handleCallback(Handler.java:883)
   at android.os.Handler.dispatchMessage(Handler.java:100)
   at android.os.Looper.loop(Looper.java:237)
   at android.app.ActivityThread.main(ActivityThread.java:7948)
   at java.lang.reflect.Method.invoke(Native method)
   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
 java.lang.reflect.InvocationTargetException
     at java.lang.reflect.Method.invoke(Native Method)
     at org.opencds.cqf.cql.engine.fhir.model.R4FhirModelResolver.initialize(R4FhirModelResolver.java:95)
     at org.opencds.cqf.cql.engine.fhir.model.FhirModelResolver.<init>(FhirModelResolver.java:56)
     at org.opencds.cqf.cql.engine.fhir.model.R4FhirModelResolver.<init>(R4FhirModelResolver.java:53)
     at org.opencds.cqf.cql.engine.fhir.model.R4FhirModelResolver.<init>(R4FhirModelResolver.java:49)
     at org.smartregister.fhircore.engine.cql.R4FhirModelResolverExt.<init>(R4FhirModelResolverExt.kt:22)
     at org.smartregister.fhircore.engine.cql.LibraryEvaluator$fhirModelResolver$2.invoke(LibraryEvaluator.kt:78)
     at org.smartregister.fhircore.engine.cql.LibraryEvaluator$fhirModelResolver$2.invoke(LibraryEvaluator.kt:78)
     at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
     at org.smartregister.fhircore.engine.cql.LibraryEvaluator.getFhirModelResolver(LibraryEvaluator.kt:78)
      at org.smartregister.fhircore.engine.cql.LibraryEvaluator.loadConfigs(LibraryEvaluator.kt:299)
      at org.smartregister.fhircore.engine.cql.LibraryEvaluator.runCqlLibrary(LibraryEvaluator.kt:221)
      at org.smartregister.fhircore.engine.cql.LibraryEvaluator$runCqlLibrary$1.invokeSuspend(Unknown Source:23)
      at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
      at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
      at android.os.Handler.handleCallback(Handler.java:883)
      at android.os.Handler.dispatchMessage(Handler.java:100)
      at android.os.Looper.loop(Looper.java:237)
      at android.app.ActivityThread.main(ActivityThread.java:7948)
      at java.lang.reflect.Method.invoke(Native Method)
      at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
  Caused by: java.lang.OutOfMemoryError: OutOfMemoryError thrown while trying to throw OutOfMemoryError; no stack trace available
f-odhiambo commented 2 years ago

Out of memory

2022-01-25 15:18:24.455 24527-24527/org.smartregister.fhircore.quest E/AndroidRuntime: FATAL EXCEPTION: main
    Process: org.smartregister.fhircore.quest, PID: 24527
    java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 2794020 bytes
        at android.app.ActivityClient.finishActivity(ActivityClient.java:156)
        at android.app.Activity.finish(Activity.java:6465)
        at android.app.Activity.finish(Activity.java:6499)
        at org.smartregister.fhircore.engine.ui.questionnaire.QuestionnaireActivity.finishActivity(QuestionnaireActivity.kt:300)
        at org.smartregister.fhircore.engine.ui.questionnaire.QuestionnaireActivity.postSaveSuccessful(QuestionnaireActivity.kt:289)
        at org.smartregister.fhircore.engine.ui.questionnaire.QuestionnaireActivity.handleQuestionnaireSubmit$lambda-4(QuestionnaireActivity.kt:267)
        at org.smartregister.fhircore.engine.ui.questionnaire.QuestionnaireActivity.$r8$lambda$Q3ZvH3-oznfR02Y6M-FSEGTDJaU(Unknown Source:0)
        at org.smartregister.fhircore.engine.ui.questionnaire.QuestionnaireActivity$$ExternalSyntheticLambda0.onChanged(Unknown Source:6)
        at androidx.lifecycle.LiveData.considerNotify(LiveData.java:133)
        at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:151)
        at androidx.lifecycle.LiveData.setValue(LiveData.java:309)
        at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
        at androidx.lifecycle.LiveData$1.run(LiveData.java:93)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:201)
        at android.os.Looper.loop(Looper.java:288)
        at android.app.ActivityThread.main(ActivityThread.java:7839)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
     Caused by: android.os.TransactionTooLargeException: data parcel size 2794020 bytes
        at android.os.BinderProxy.transactNative(Native Method)
        at android.os.BinderProxy.transact(BinderProxy.java:571)
        at android.app.IActivityClientController$Stub$Proxy.finishActivity(IActivityClientController.java:1496)
        at android.app.ActivityClient.finishActivity(ActivityClient.java:153)
        at android.app.Activity.finish(Activity.java:6465) 
        at android.app.Activity.finish(Activity.java:6499) 
        at org.smartregister.fhircore.engine.ui.questionnaire.QuestionnaireActivity.finishActivity(QuestionnaireActivity.kt:300) 
        at org.smartregister.fhircore.engine.ui.questionnaire.QuestionnaireActivity.postSaveSuccessful(QuestionnaireActivity.kt:289) 
        at org.smartregister.fhircore.engine.ui.questionnaire.QuestionnaireActivity.handleQuestionnaireSubmit$lambda-4(QuestionnaireActivity.kt:267) 
        at org.smartregister.fhircore.engine.ui.questionnaire.QuestionnaireActivity.$r8$lambda$Q3ZvH3-oznfR02Y6M-FSEGTDJaU(Unknown Source:0) 
        at org.smartregister.fhircore.engine.ui.questionnaire.QuestionnaireActivity$$ExternalSyntheticLambda0.onChanged(Unknown Source:6) 
        at androidx.lifecycle.LiveData.considerNotify(LiveData.java:133) 
        at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:151) 
        at androidx.lifecycle.LiveData.setValue(LiveData.java:309) 
        at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50) 
        at androidx.lifecycle.LiveData$1.run(LiveData.java:93) 
        at android.os.Handler.handleCallback(Handler.java:938) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loopOnce(Looper.java:201) 
        at android.os.Looper.loop(Looper.java:288) 
        at android.app.ActivityThread.main(ActivityThread.java:7839) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003) 

CC @maimoonak @FikriMilano

FikriMilano commented 2 years ago

Noted @f-odhiambo @maimoonak

FikriMilano commented 2 years ago

I managed to fix this by running the CQL in parallel and move it's process to background thread. It takes ~30 seconds to process after submitting, first time submitting might take up to 1 minute. The process is heavy because of the image and CQL. @f-odhiambo @maimoonak

maimoonak commented 2 years ago

@FikriMilano But it would still keep user blocked or on progress unless cql is also finished... If not can we do so, i.e. do not let user finish activity until everything is done.. otherwise app would show inaccurate data.

FikriMilano commented 2 years ago

@maimoonak yeah I did exactly that, the activity won't finish until everything is done. So the user will keep seeing the loading bar for 30 to 60 seconds until all process is done, then finish the activity.