Skip to content

[MS-1068] Navigation crash upon state restoration#1609

Open
BurningAXE wants to merge 3 commits intomainfrom
MS-1068-Navigation-crash-upon-state-restoration
Open

[MS-1068] Navigation crash upon state restoration#1609
BurningAXE wants to merge 3 commits intomainfrom
MS-1068-Navigation-crash-upon-state-restoration

Conversation

@BurningAXE
Copy link
Contributor

JIRA ticket
Will be released in: 2026.2.0

Root cause analysis (for bugfixes only)

First known affected version: since last major refactor

  • In FaceCaptureControllerFragment nav graph is set after result handlers
  • canNavigate() does not protect against graph not set (null currentDestination)
  • As a result the following situation leads to a crash:
  1. A workflow is initiated and face capture step is reached
  2. User navigates to the exit screen
  3. App is minimized and then gets killed by the OS (can be simulated with "Don't keep activities")
  4. App is brought to the foreground
  5. User presses the "Capture biometrics" button on the exit screen
  6. In FaceCaptureControllerFragment exit screen handler tries to navigate but graph is not yet set
  7. KABOOM

Notable changes

  • Moves setGraph() before result handlers so it's set before any result handler can fire
  • ExternalCredentialControllerFragment was also vulnerable to this so the same change was applied there
  • In addition, canNavigate() was updated to return false if currentDestination is null. This would prevent crashing if similar situation arises elsewhere (although user might get stuck).

Testing guidance

  • Go through the reproduction steps - #7 should not happen :D

Additional work checklist

  • Effect on other features and security has been considered
  • Design document marked as "In development" (if applicable)
  • External (Gitbook) and internal (Confluence) Documentation is up to date (or ticket created)
  • Test cases in Testiny are up to date (or ticket created)
  • Other teams notified about the changes (if applicable)

@cla-bot cla-bot bot added the ... label Mar 6, 2026
@BurningAXE BurningAXE requested a review from Copilot March 6, 2026 15:10
@BurningAXE BurningAXE marked this pull request as ready for review March 6, 2026 15:10
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a crash during process-death state restoration where result callbacks can fire before an internal NavHostFragment’s graph is set (notably in face capture and external credential controllers), causing navigation to run against a NavController with no currentDestination.

Changes:

  • Reorders internal NavController.setGraph(...) to occur before registering handleResult(...) callbacks in controller fragments.
  • Updates NavController.canNavigate(...) to return false when currentDestination is null, preventing navigation attempts before a graph is set.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
infra/ui-base/src/main/java/com/simprints/infra/uibase/navigation/NavigationResultExt.kt Tightens canNavigate() to block navigation when currentDestination is null (graph not set).
feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/controller/ExternalCredentialControllerFragment.kt Sets internal graph before registering result handlers to avoid early callback navigation crashes.
face/capture/src/main/java/com/simprints/face/capture/screens/controller/FaceCaptureControllerFragment.kt Sets internal graph (with dynamic start destination) before result handlers to avoid early callback navigation crashes.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +193 to +196
currentFragment ?: return false
val currentDest = currentDestination ?: return false
val targetClassName = (currentDest as? FragmentNavigator.Destination)?.className
return targetClassName == null || targetClassName == currentFragment::class.java.name
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

canNavigate() now returns false when currentDestination is null. That will route more cases through navigateIfPossible’s failure branch, which logs a Simber.w(..., IllegalStateException(...)). In release builds, Simber.w is forwarded to Crashlytics and records the exception, so this change can create noisy non-fatal Crashlytics issues during state restoration/graph setup races. Consider special-casing the currentDestination == null path to log without a throwable (or at info) and/or include a clearer message like “Nav graph not set yet” so it’s actionable without polluting Crashlytics.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's an exceptional situation that we do want to get informed about.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 6, 2026

@BurningAXE BurningAXE requested review from a team, TristramN, alex-vt, alexandr-simprints, luhmirin-s, meladRaouf and ybourgery and removed request for a team March 6, 2026 15:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants