Wordpress-android: Crash in StatsDateFormatter.kt: Unparseable date: ""

Created on 2 Jan 2019  路  7Comments  路  Source: wordpress-mobile/WordPress-Android

This was introduced in 11.5-rc-1 and has already been reported in Fabric >500 times.

I don't have clear steps but it seems to be caused by StatsDateFormatter.kt attempting to parse an empty date: Unparseable date: ""

Here is the stacktrace:

Fatal Exception: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)

Caused by java.lang.reflect.InvocationTargetException
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)

Caused by java.text.ParseException: Unparseable date: ""
       at java.text.DateFormat.parse(DateFormat.java:358)
       at org.wordpress.android.ui.stats.refresh.utils.StatsDateFormatter.parseStatsDate(StatsDateFormatter.kt:117)
       at org.wordpress.android.ui.stats.refresh.lists.sections.granular.usecases.OverviewUseCase.buildStatefulUiModel(OverviewUseCase.kt:81)
       at org.wordpress.android.ui.stats.refresh.lists.sections.granular.usecases.OverviewUseCase.buildStatefulUiModel(OverviewUseCase.kt:25)
       at org.wordpress.android.ui.stats.refresh.lists.sections.BaseStatsUseCase$StatefulUseCase.buildUiModel(BaseStatsUseCase.kt:165)
       at org.wordpress.android.ui.stats.refresh.lists.sections.BaseStatsUseCase$liveData$1.invoke(BaseStatsUseCase.kt:33)
       at org.wordpress.android.ui.stats.refresh.lists.sections.BaseStatsUseCase$liveData$1.invoke(BaseStatsUseCase.kt:22)
       at org.wordpress.android.util.LiveDataUtilsKt$merge$3.invoke(LiveDataUtils.kt:76)
       at org.wordpress.android.util.LiveDataUtilsKt$merge$3.invoke(LiveDataUtils.kt)
       at org.wordpress.android.util.LiveDataUtilsKt$map$1.apply(LiveDataUtils.kt:132)
       at android.arch.lifecycle.Transformations$1.onChanged(Transformations.java:70)
       at android.arch.lifecycle.MediatorLiveData$Source.onChanged(MediatorLiveData.java:152)
       at android.arch.lifecycle.LiveData.considerNotify(LiveData.java:109)
       at android.arch.lifecycle.LiveData.dispatchingValue(LiveData.java:126)
       at android.arch.lifecycle.LiveData.setValue(LiveData.java:282)
       at android.arch.lifecycle.MutableLiveData.setValue(MutableLiveData.java:33)
       at org.wordpress.android.util.LiveDataUtilsKt$merge$1.onChanged(LiveDataUtils.kt:71)
       at android.arch.lifecycle.MediatorLiveData$Source.onChanged(MediatorLiveData.java:152)
       at android.arch.lifecycle.LiveData.considerNotify(LiveData.java:109)
       at android.arch.lifecycle.LiveData.dispatchingValue(LiveData.java:121)
       at android.arch.lifecycle.LiveData.access$400(LiveData.java:59)
       at android.arch.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:416)
       at android.arch.lifecycle.LiveData.observeForever(LiveData.java:207)
       at android.arch.lifecycle.MediatorLiveData$Source.plug(MediatorLiveData.java:141)
       at android.arch.lifecycle.MediatorLiveData.onActive(MediatorLiveData.java:118)
       at android.arch.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:410)
       at android.arch.lifecycle.LiveData.observeForever(LiveData.java:207)
       at android.arch.lifecycle.MediatorLiveData$Source.plug(MediatorLiveData.java:141)
       at android.arch.lifecycle.MediatorLiveData.onActive(MediatorLiveData.java:118)
       at android.arch.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:410)
       at android.arch.lifecycle.LiveData.observeForever(LiveData.java:207)
       at android.arch.lifecycle.MediatorLiveData$Source.plug(MediatorLiveData.java:141)
       at android.arch.lifecycle.MediatorLiveData.onActive(MediatorLiveData.java:118)
       at android.arch.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:410)
       at android.arch.lifecycle.LiveData.observeForever(LiveData.java:207)
       at android.arch.lifecycle.MediatorLiveData$Source.plug(MediatorLiveData.java:141)
       at android.arch.lifecycle.MediatorLiveData.onActive(MediatorLiveData.java:118)
       at android.arch.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:410)
       at android.arch.lifecycle.LiveData.observeForever(LiveData.java:207)
       at android.arch.lifecycle.MediatorLiveData$Source.plug(MediatorLiveData.java:141)
       at android.arch.lifecycle.MediatorLiveData.onActive(MediatorLiveData.java:118)
       at android.arch.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:410)
       at android.arch.lifecycle.LiveData.observeForever(LiveData.java:207)
       at android.arch.lifecycle.MediatorLiveData$Source.plug(MediatorLiveData.java:141)
       at android.arch.lifecycle.MediatorLiveData.onActive(MediatorLiveData.java:118)
       at android.arch.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:410)
       at android.arch.lifecycle.LiveData$LifecycleBoundObserver.onStateChanged(LiveData.java:368)
       at android.arch.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:354)
       at android.arch.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:292)
       at android.arch.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:332)
       at android.arch.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:137)
       at android.arch.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:123)
       at android.support.v4.app.Fragment.performStart(Fragment.java:2380)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1467)
       at android.support.v4.app.FragmentManagerImpl.performPendingDeferredStart(FragmentManager.java:1232)
       at android.support.v4.app.FragmentManagerImpl.startPendingDeferredFragments(FragmentManager.java:1855)
       at android.support.v4.app.FragmentManagerImpl.doPendingDeferredStart(FragmentManager.java:2697)
       at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:2221)
       at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:649)
       at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:145)
       at android.support.v4.view.ViewPager.populate(ViewPager.java:1238)
       at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:663)
       at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:625)
       at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:606)
       at android.support.design.widget.TabLayout$ViewPagerOnTabSelectedListener.onTabSelected(TabLayout.java:2170)
       at android.support.design.widget.TabLayout.dispatchTabSelected(TabLayout.java:1165)
       at android.support.design.widget.TabLayout.selectTab(TabLayout.java:1158)
       at android.support.design.widget.TabLayout.selectTab(TabLayout.java:1128)
       at android.support.design.widget.TabLayout$Tab.select(TabLayout.java:1427)
       at android.support.design.widget.TabLayout$TabView.performClick(TabLayout.java:1537)
       at android.view.View$PerformClick.run(View.java:22693)
       at android.os.Handler.handleCallback(Handler.java:836)
       at android.os.Handler.dispatchMessage(Handler.java:103)
       at android.os.Looper.loop(Looper.java:203)
       at android.app.ActivityThread.main(ActivityThread.java:6269)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)

Reference: 5c230708f8b88c296335ea8a-fabric

cc @jkmassel

Stats Refresh [Pri] High [Type] Crash

Most helpful comment

I can reproduce this crash by using a brand-new WordPress.com site with no views/visits. When I open Stats I can view the Insights tab without any trouble, but when I try to open a different stats tab (e.g. Days or Weeks) the app crashes.

To reproduce:

  1. Create a new WordPress.com site (with a new or existing account).
  2. Go to My Sites > Stats.
  3. Select a tab like Days. 馃挜

All 7 comments

cc @planarvoid @0nko

Unfortunately, this crash still seems to be occurring on 11.5 which includes the fix from https://github.com/wordpress-mobile/WordPress-Android/pull/8922. Its possible its less common now, but its hard to tell.

This crash may also be related: https://github.com/wordpress-mobile/WordPress-FluxC-Android/issues/1073

cc @0nko

I can reproduce this crash by using a brand-new WordPress.com site with no views/visits. When I open Stats I can view the Insights tab without any trouble, but when I try to open a different stats tab (e.g. Days or Weeks) the app crashes.

To reproduce:

  1. Create a new WordPress.com site (with a new or existing account).
  2. Go to My Sites > Stats.
  3. Select a tab like Days. 馃挜

Thanks for digging into this @rachelmcr! I have also been able to reproduce this with your steps. It did also crash for a (mostly unused) test site but thats not consistent.

The cause seems to be that there is data missing for certain dates.

@0nko I attached the debugger to see what is happening and I can see that domainModel.dates is not empty for these crashing cases, which is why the fix didn't work.

image

I have fixed an API issue where invalid data (empty date) would be returned for new sites in D23272.

This has fixed the crash. I can no longer reproduce it and it reports have stopped coming into Fabric.

This seems to have reoccurred starting in 12.1-rc-2. It is alreadfy the most common crash in 12.1:

Fatal Exception: java.text.ParseException: Unparseable date: ""
       at java.text.DateFormat.parse(DateFormat.java:362)
       at org.wordpress.android.ui.stats.refresh.utils.StatsDateFormatter.printDate(StatsDateFormatter.java:58)
       at org.wordpress.android.ui.stats.refresh.lists.sections.insights.usecases.AllTimeStatsUseCase.buildUiModel(AllTimeStatsUseCase.java:75)
       at org.wordpress.android.ui.stats.refresh.lists.sections.insights.usecases.AllTimeStatsUseCase.buildUiModel(AllTimeStatsUseCase.java:22)
       at org.wordpress.android.ui.stats.refresh.lists.sections.BaseStatsUseCase$StatelessUseCase.buildUiModel(BaseStatsUseCase.java:254)
       at org.wordpress.android.ui.stats.refresh.lists.sections.BaseStatsUseCase$StatelessUseCase.buildUiModel(BaseStatsUseCase.java:239)
       at org.wordpress.android.ui.stats.refresh.lists.sections.BaseStatsUseCase$liveData$1.invoke(BaseStatsUseCase.java:41)
       at org.wordpress.android.ui.stats.refresh.lists.sections.BaseStatsUseCase$liveData$1.invoke(BaseStatsUseCase.java:28)
       at org.wordpress.android.util.LiveDataUtilsKt$merge$7.invoke(LiveDataUtilsKt.java:131)
       at org.wordpress.android.util.LiveDataUtilsKt$merge$7.invoke(LiveDataUtilsKt.java:2)
       at org.wordpress.android.util.LiveDataUtilsKt$map$1.onChanged(LiveDataUtilsKt.java:163)
       at android.arch.lifecycle.MediatorLiveData$Source.onChanged(MediatorLiveData.java:152)
       at android.arch.lifecycle.LiveData.considerNotify(LiveData.java:109)
       at android.arch.lifecycle.LiveData.dispatchingValue(LiveData.java:126)
       at android.arch.lifecycle.LiveData.setValue(LiveData.java:282)
       at android.arch.lifecycle.MutableLiveData.setValue(MutableLiveData.java:33)
       at org.wordpress.android.util.LiveDataUtilsKt$merge$4.onChanged(LiveDataUtilsKt.java:118)
       at android.arch.lifecycle.MediatorLiveData$Source.onChanged(MediatorLiveData.java:152)
       at android.arch.lifecycle.LiveData.considerNotify(LiveData.java:109)
       at android.arch.lifecycle.LiveData.dispatchingValue(LiveData.java:126)
       at android.arch.lifecycle.LiveData.setValue(LiveData.java:282)
       at android.arch.lifecycle.MutableLiveData.setValue(MutableLiveData.java:33)
       at org.wordpress.android.util.LiveDataUtilsKt$distinct$1.onChanged(LiveDataUtilsKt.java:191)
       at android.arch.lifecycle.MediatorLiveData$Source.onChanged(MediatorLiveData.java:152)
       at android.arch.lifecycle.LiveData.considerNotify(LiveData.java:109)
       at android.arch.lifecycle.LiveData.dispatchingValue(LiveData.java:126)
       at android.arch.lifecycle.LiveData.setValue(LiveData.java:282)
       at android.arch.lifecycle.MutableLiveData.setValue(MutableLiveData.java:33)
       at org.wordpress.android.ui.stats.refresh.lists.sections.BaseStatsUseCase$evaluateState$useCaseState$1.invokeSuspend(BaseStatsUseCase.java:104)
       at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(BaseContinuationImpl.java:32)
       at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.java:233)
       at android.os.Handler.handleCallback(Handler.java:873)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:193)
       at android.app.ActivityThread.main(ActivityThread.java:6692)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

5ca00a44f8b88c29639d1adb-fabric

@planarvoid if you think this is a different issue we can open a new one instead.

Fixed in alpha-163 and 12.2-rc-2. Props @planarvoid. 馃帀

Was this page helpful?
0 / 5 - 0 ratings