Skip to content

Commit 8eb4240

Browse files
fix: add null checks for getViewState in SurfaceMountingManager (#57283)
Summary: Fix SurfaceMountingManager null handling for methods that can be invoked after a view has been deleted or is otherwise missing. sendAccessibilityEvent and setJSResponder now use getNullableViewState(...) and guard against missing ViewState before accessing .view, logging a soft exception and returning instead of crashing. Also removed the now-unused getViewState helper. ## Changelog: [ANDROID][FIXED] Avoid crash in SurfaceMountingManager when sendAccessibilityEvent or setJSResponder is called for a missing or deleted view state. Pull Request resolved: #57283 Test Plan: This is a safe check added to avoid crashing the application with reference to similiar checks added in other related methods. Reviewed By: fabriziocucci Differential Revision: D109834942 Pulled By: javache fbshipit-source-id: 75d6e5e646f78efe9456aaacafd40b05362003d7
1 parent 8371983 commit 8eb4240

1 file changed

Lines changed: 22 additions & 13 deletions

File tree

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.kt

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -760,9 +760,16 @@ internal constructor(
760760
return
761761
}
762762

763-
val view = getViewState(reactTag).view
763+
val viewState = getNullableViewState(reactTag)
764+
val view = viewState?.view
764765
if (view == null) {
765-
throw RetryableMountingLayerException("Unable to find viewState view for tag $reactTag")
766+
ReactSoftExceptionLogger.logSoftException(
767+
ReactSoftExceptionLogger.Categories.SURFACE_MOUNTING_MANAGER_MISSING_VIEWSTATE,
768+
ReactNoCrashSoftException(
769+
"Unable to find viewState for tag $reactTag for sendAccessibilityEvent"
770+
),
771+
)
772+
return
766773
}
767774

768775
view.sendAccessibilityEvent(eventType)
@@ -1004,16 +1011,24 @@ internal constructor(
10041011
return
10051012
}
10061013

1007-
val viewState = getViewState(reactTag)
1008-
val view = viewState.view
1014+
val viewState = getNullableViewState(reactTag)
1015+
1016+
val view = viewState?.view
1017+
if (view == null) {
1018+
ReactSoftExceptionLogger.logSoftException(
1019+
ReactSoftExceptionLogger.Categories.SURFACE_MOUNTING_MANAGER_MISSING_VIEWSTATE,
1020+
ReactNoCrashSoftException(
1021+
"Unable to find viewState for tag $reactTag for setJSResponder"
1022+
),
1023+
)
1024+
return
1025+
}
1026+
10091027
if (initialReactTag != reactTag && view is ViewParent) {
10101028
// In this case, initialReactTag corresponds to a virtual/layout-only View, and we already
10111029
// have a parent of that View in reactTag, so we can use it.
10121030
jsResponderHandler.setJSResponder(initialReactTag, view as ViewParent)
10131031
return
1014-
} else if (view == null) {
1015-
SoftAssertions.assertUnreachable("Cannot find view for tag [$reactTag].")
1016-
return
10171032
}
10181033

10191034
if (viewState.isRoot) {
@@ -1122,12 +1137,6 @@ internal constructor(
11221137
)
11231138
}
11241139

1125-
private fun getViewState(reactTag: Int): ViewState =
1126-
getNullableViewState(reactTag)
1127-
?: throw RetryableMountingLayerException(
1128-
"Unable to find viewState for tag $reactTag. Surface stopped: $isStopped"
1129-
)
1130-
11311140
private fun getNullableViewState(reactTag: Int): ViewState? = registryLock.read {
11321141
tagToViewState[reactTag]
11331142
}

0 commit comments

Comments
 (0)