ADFA-3472: Guard BuildOutputFragment access when detached#1415
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 Walkthrough
Walkthrough
ChangesDetached Fragment Crash Fix
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Sentry APPDEVFORALL-N4. Skip activityViewModels access when the fragment is detached; guard the caller with isAdded. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reproduces the Sentry IllegalStateException ('not attached to an activity')
thrown when clearOutput()/getShareableContent() force the activityViewModels
lazy delegate (-> requireActivity()) on a detached fragment. RED on the
pre-fix baseline (4d9b100), GREEN with the isAdded/activity guard.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
64ac5df to
e6941b4
Compare
Jira Ticket: https://appdevforall.atlassian.net/browse/ADFA-3472
Sentry Issue: https://appdevforall-inc-9p.sentry.io/issues/APPDEVFORALL-N4
Question
Looks like this file is part of AndroidIDE -- do we make changes here or upstream?
Reproduction Details
BuildOutputFragmentholdsbuildOutputViewModelviaby activityViewModels(). WhenclearOutput()/getShareableContent()run on a detached fragment, forcing that lazy delegate callsrequireActivity(), which throwsIllegalStateException: … not attached to an activity.Stack Trace
User Steps
User steps leading up to crash, based on Sentry breadcrumbs:
BuildOutputFragmentgoes through save-state → stopped → view destroyed → detached, and an incoming build-output update then callsclearOutput()on the now-detached fragment → crash.Was able to reproduce in a unit test?
Yes.
BuildOutputFragmentDetachedTest(:app, Robolectric) constructs a never-attached fragment (isAdded == false) and calls each method. Baseline: both FAIL withIllegalStateExceptionatrequireActivityvia theactivityViewModelsdelegate; branch: both pass.What Was Fixed
if (!isAdded || activity == null) returnguard inclearOutput()/getShareableContent()(returns "" for the latter) before touching the activity-scoped view model.Testing
:app:testV8DebugUnitTest→ 2/2 green (red on baseline). Local CodeRabbit review: no findings. Reviewer note (local): theactivity == nullclause is redundant with!isAdded, andEditorBottomSheet'stakeIf { it.isAdded }is now belt-and-suspenders — harmless.viewLifecycleOwneris NOT the right alternative here (the precondition isisAdded, which it doesn't capture).Fixes APPDEVFORALL-N4