From 48c69af3e0b36091c0c79b1690b33fbdc5cb6d9d Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Thu, 5 Dec 2019 13:16:09 -0800 Subject: [PATCH] Throw non-crashing SoftException when ViewCommand is sent to non-existent tag Summary: Motivation: TextInput.js frequently sends commands to views as they're disappearing (`blur`, for instance). We should fix that in the future, if possible. For now, just log the issue and continue. It shouldn't cause any user-facing issues since 1) it appears that TextInput knows the underlying view is gone; 2) the View has already disappeared so the user can't interact with it, so commands can go safely into the void. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D18821448 fbshipit-source-id: 980dbbce8cdb2cc0bb4bf60b3bccc90869208f01 --- .../facebook/react/fabric/mounting/MountingManager.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) 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 30a74cfa55a..1e94ac56f44 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 @@ -20,6 +20,7 @@ import androidx.annotation.Nullable; import androidx.annotation.UiThread; import com.facebook.infer.annotation.Assertions; import com.facebook.infer.annotation.ThreadConfined; +import com.facebook.react.bridge.ReactNoCrashSoftException; import com.facebook.react.bridge.ReactSoftException; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; @@ -138,10 +139,15 @@ public class MountingManager { public void receiveCommand(int reactTag, int commandId, @Nullable ReadableArray commandArgs) { ViewState viewState = getNullableViewState(reactTag); + // It's not uncommon for JS to send events as/after a component is being removed from the + // view hierarchy. For example, TextInput may send a "blur" command in response to the view + // disappearing. Throw `ReactNoCrashSoftException` so they're logged but don't crash in dev + // for now. + // TODO T58653970: Crash in debug again and fix all the places that cause this to crash. if (viewState == null) { ReactSoftException.logSoftException( MountingManager.TAG, - new IllegalStateException( + new ReactNoCrashSoftException( "Unable to find viewState for tag: " + reactTag + " for commandId: " + commandId)); return; }