diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java index 9dca8b0a37361f..53f31f3cd570a3 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java @@ -945,7 +945,7 @@ private ThemedReactContext getReactContextForView(int reactTag) { public void sendAccessibilityEvent(int tag, int eventType) { View view = mTagsToViews.get(tag); if (view == null) { - throw new JSApplicationIllegalArgumentException("Could not find view with tag " + tag); + throw new RetryableMountingLayerException("Could not find view with tag " + tag); } view.sendAccessibilityEvent(eventType); } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java index 93ccb0a9fbf98b..de3ca5db4f1899 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java @@ -591,7 +591,18 @@ private SendAccessibilityEvent(int tag, int eventType) { @Override public void execute() { - mNativeViewHierarchyManager.sendAccessibilityEvent(mTag, mEventType); + try { + mNativeViewHierarchyManager.sendAccessibilityEvent(mTag, mEventType); + } catch (RetryableMountingLayerException e) { + // Accessibility events are similar to commands in that they're imperative + // calls from JS, disconnected from the commit lifecycle, and therefore + // inherently unpredictable and dangerous. If we encounter a "retryable" + // error, that is, a known category of errors that this is likely to hit + // due to race conditions (like the view disappearing after the event is + // queued and before it executes), we log a soft exception and continue along. + // Other categories of errors will still cause a hard crash. + ReactSoftExceptionLogger.logSoftException(TAG, e); + } } }