diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java index 6d249b1fd08..3cedf09033c 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java @@ -138,7 +138,7 @@ public class MountingManager { private @NonNull ViewState getViewState(int tag) { ViewState viewState = mTagToViewState.get(tag); if (viewState == null) { - throw new IllegalStateException("Unable to find viewState view for tag " + tag); + throw new RetryableMountingLayerException("Unable to find viewState view for tag " + tag); } return viewState; } @@ -202,11 +202,13 @@ public class MountingManager { ViewState viewState = getViewState(reactTag); if (viewState.mViewManager == null) { - throw new IllegalStateException("Unable to find viewState manager for tag " + reactTag); + throw new RetryableMountingLayerException( + "Unable to find viewState manager for tag " + reactTag); } if (viewState.mView == null) { - throw new IllegalStateException("Unable to find viewState view for tag " + reactTag); + throw new RetryableMountingLayerException( + "Unable to find viewState view for tag " + reactTag); } viewState.mView.sendAccessibilityEvent(eventType); diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/SendAccessibilityEvent.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/SendAccessibilityEvent.java index 207d79871cc..5852ff1a78c 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/SendAccessibilityEvent.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/SendAccessibilityEvent.java @@ -8,10 +8,14 @@ package com.facebook.react.fabric.mounting.mountitems; import androidx.annotation.NonNull; +import com.facebook.react.bridge.ReactSoftException; +import com.facebook.react.bridge.RetryableMountingLayerException; import com.facebook.react.fabric.mounting.MountingManager; public class SendAccessibilityEvent implements MountItem { + private final String TAG = "Fabric.SendAccessibilityEvent"; + private final int mReactTag; private final int mEventType; @@ -22,7 +26,18 @@ public class SendAccessibilityEvent implements MountItem { @Override public void execute(@NonNull MountingManager mountingManager) { - mountingManager.sendAccessibilityEvent(mReactTag, mEventType); + try { + mountingManager.sendAccessibilityEvent(mReactTag, 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. + ReactSoftException.logSoftException(TAG, e); + } } @Override