Conversation
There was a problem hiding this comment.
Pull request overview
Updates the ExPlat (Automattic experimentation) integration to prevent user-facing crashes caused by unreadable/corrupted cached experiment data, primarily by bumping the library version and hardening initialization/execution error handling.
Changes:
- Bump Automattic Tracks/ExPlat dependency from
6.0.7to6.0.8(upstream fix for the known cache/schema crash). - Guard
ExperimentProvider.initialize(...)withrunCatchingto avoid crashing on initialization failures. - Provide ExPlat with a
SupervisorJob-backed coroutine scope plus aCoroutineExceptionHandlerthat logs and clears the experiments cache directory on uncaught coroutine errors.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| modules/services/analytics/src/main/java/au/com/shiftyjelly/pocketcasts/analytics/experiments/ExperimentProvider.kt | Wraps repository initialization in runCatching to prevent crashes during ExPlat init. |
| modules/services/analytics/src/main/java/au/com/shiftyjelly/pocketcasts/analytics/di/AnalyticsModule.kt | Switches ExPlat scope to SupervisorJob + CoroutineExceptionHandler and clears cache on uncaught exceptions. |
| gradle/libs.versions.toml | Bumps Tracks/ExPlat version to 6.0.8. |
...ics/src/main/java/au/com/shiftyjelly/pocketcasts/analytics/experiments/ExperimentProvider.kt
Show resolved
Hide resolved
...ics/src/main/java/au/com/shiftyjelly/pocketcasts/analytics/experiments/ExperimentProvider.kt
Show resolved
Hide resolved
...vices/analytics/src/main/java/au/com/shiftyjelly/pocketcasts/analytics/di/AnalyticsModule.kt
Outdated
Show resolved
Hide resolved
ba90379 to
96d67f8
Compare
| runCatching { | ||
| repository.initialize(anonymousId = uuid, oAuthToken = null) | ||
| }.onFailure { throwable -> | ||
| LogBuffer.e(TAG, throwable, "Failed to initialize experiments") | ||
| runCatching { repository.clear() } | ||
| } |
There was a problem hiding this comment.
The new runCatching/onFailure behavior in initialize(uuid) (swallowing init exceptions and clearing the repository) isn’t covered by unit tests. Please add a test that stubs repository.initialize(...) to throw and asserts initialize(uuid) does not rethrow and triggers repository.clear().
| val deleted = runCatching { directory.deleteRecursively() }.getOrDefault(false) | ||
| if (deleted) { | ||
| LogBuffer.i(ExperimentProvider.TAG, "Cleared corrupted experiment cache") | ||
| } else { | ||
| LogBuffer.e(ExperimentProvider.TAG, "Failed to clear corrupted experiment cache") | ||
| } |
There was a problem hiding this comment.
File.deleteRecursively() returns false when the directory doesn’t exist, which would log "Failed to clear corrupted experiment cache" even though there may be nothing to clear (or it was already deleted). Consider treating a missing directory as a successful clear (e.g., !exists() || deleteRecursively()), to avoid noisy/misleading error logs.
Project dependencies changeslist! Upgraded Dependencies
com.automattic.tracks:crashlogging:6.0.8, (changed from 6.0.7)
com.automattic.tracks:experimentation:6.0.8, (changed from 6.0.7)
com.automattic:Automattic-Tracks-Android:6.0.8, (changed from 6.0.7)tree-+--- com.automattic.tracks:crashlogging:6.0.7
++--- com.automattic.tracks:crashlogging:6.0.8
+--- project :modules:features:account
| +--- project :modules:features:search
| | +--- project :modules:services:analytics
| | | +--- project :modules:services:servers
-| | | | \--- com.automattic.tracks:crashlogging:6.0.7 (*)
+| | | | \--- com.automattic.tracks:crashlogging:6.0.8 (*)
-| | | +--- com.automattic.tracks:experimentation:6.0.7
+| | | +--- com.automattic.tracks:experimentation:6.0.8
-| | | \--- com.automattic:Automattic-Tracks-Android:6.0.7
+| | | \--- com.automattic:Automattic-Tracks-Android:6.0.8
| | +--- project :modules:services:repositories
| | | \--- project :modules:services:crashlogging
-| | | \--- com.automattic.tracks:crashlogging:6.0.7 (*)
+| | | \--- com.automattic.tracks:crashlogging:6.0.8 (*)
| | \--- project :modules:services:views
-| | \--- com.automattic.tracks:crashlogging:6.0.7 (*)
+| | \--- com.automattic.tracks:crashlogging:6.0.8 (*)
| \--- project :modules:features:settings
-| \--- com.automattic.tracks:crashlogging:6.0.7 (*)
+| \--- com.automattic.tracks:crashlogging:6.0.8 (*)
+--- project :modules:features:discover
-| \--- com.automattic.tracks:crashlogging:6.0.7 (*)
+| \--- com.automattic.tracks:crashlogging:6.0.8 (*)
+--- project :modules:features:endofyear
-| \--- com.automattic.tracks:crashlogging:6.0.7 (*)
+| \--- com.automattic.tracks:crashlogging:6.0.8 (*)
\--- project :modules:features:profile
- \--- com.automattic.tracks:crashlogging:6.0.7 (*)
+ \--- com.automattic.tracks:crashlogging:6.0.8 (*) |
Description
This PR addresses a crash reported by one of our users via ZenDesk. It stemmed from ExPlat, happened when a cached experiment's json schema was no longer recognised by the library.
This was a known issue and was fixed with ExPlat v 6.0.8, so I updated our library to this version.
On top of that I've added safeguards so this should never happen again:
SupervisorJobthat logs errors instead of crashing + clears cache on issueFixes PCDROID-523
Testing Instructions
As I found no easy way to replicate the OG issue, just review the code pls.
Checklist
./gradlew spotlessApplyto automatically apply formatting/linting)modules/services/localization/src/main/res/values/strings.xml