From 2151d1152719a230565165f1a8dcfab172689eb3 Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Tue, 18 Jan 2022 16:13:56 -0800 Subject: [PATCH] Fix T110060790 Summary: In the case of T110060790, there is a JavaScript crash that causes RN teardown to race with a ScrollView event being emitted, which ends up being reported as the "real" cause of the crash. This is not correct, and it's better to just ignore this case. If there's no EventDispatcher, it means something has gone wrong (usually teardown) before, RN is in an inconsistent state, and we should not crash here or report here. Changelog: [Android][Fixed] Fix crash from ScrollView that occurs while reporting an error from JS Reviewed By: mdvacca Differential Revision: D33644692 fbshipit-source-id: 41c3defde795b804239cc8401c8aff71d017d59d --- .../views/scroll/ReactScrollViewHelper.java | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.java index 36949c01307f7e..c8ae52828c76ef 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.java @@ -27,6 +27,7 @@ import com.facebook.react.uimanager.UIManagerHelper; import com.facebook.react.uimanager.common.UIManagerType; import com.facebook.react.uimanager.common.ViewUtil; +import com.facebook.react.uimanager.events.EventDispatcher; import java.util.Collections; import java.util.Set; import java.util.WeakHashMap; @@ -107,20 +108,28 @@ private static void emitScrollEvent( ReactContext reactContext = (ReactContext) scrollView.getContext(); int surfaceId = UIManagerHelper.getSurfaceId(reactContext); - UIManagerHelper.getEventDispatcherForReactTag(reactContext, scrollView.getId()) - .dispatchEvent( - ScrollEvent.obtain( - surfaceId, - scrollView.getId(), - scrollEventType, - scrollView.getScrollX(), - scrollView.getScrollY(), - xVelocity, - yVelocity, - contentView.getWidth(), - contentView.getHeight(), - scrollView.getWidth(), - scrollView.getHeight())); + + // It's possible for the EventDispatcher to go away - for example, + // if there's a crash initiated from JS and we tap on a ScrollView + // around teardown of RN, this will cause a NPE. We can safely ignore + // this since the crash is usually a red herring. + EventDispatcher eventDispatcher = + UIManagerHelper.getEventDispatcherForReactTag(reactContext, scrollView.getId()); + if (eventDispatcher != null) { + eventDispatcher.dispatchEvent( + ScrollEvent.obtain( + surfaceId, + scrollView.getId(), + scrollEventType, + scrollView.getScrollX(), + scrollView.getScrollY(), + xVelocity, + yVelocity, + contentView.getWidth(), + contentView.getHeight(), + scrollView.getWidth(), + scrollView.getHeight())); + } } /** This is only for Java listeners. onLayout events emitted to JS are handled elsewhere. */