From 090196f330b40b63d6201f7253683f410fa812b2 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Fri, 23 Apr 2021 15:11:28 -0700 Subject: [PATCH] ReactContext: Fail fast when NativeModules thread is null Summary: By the time that we call [ReactContext.assertOnNativeModulesQueueThread()](https://www.internalfb.com/intern/diffusion/FBS/browsefile/master/xplat/js/react-native-github/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java?commit=747a25280435d276fb975ccfe36fd5e60254c4e4&lines=355%2C359), ReactContext.mNativeModulesMessageQueueThread must be non-null. This implies that two things must have happened: 1. We initialized the ReactContext 2. After initialization, ReactContext.mNativeModulesMessageQueueThread must be non-null. According to T85807990, ReactContext.mNativeModulesMessageQueueThread is null. Since ReactContext doesn't ever write to ReactContext.mNativeModulesMessageQueueThread aside from during initialization, it must mean that we either didn't initialize properly, or we initialized, but set the NativeModules thread to null. This diff throws IllegalStateExceptions inside ReactContext initialization, which should help narrow down the crash in T85807990. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D27729355 fbshipit-source-id: e39030b7db8862ae76fb644efaafb382a79b8ad0 --- .../facebook/react/bridge/ReactContext.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java index f227f0da062..9caaeff3508 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java @@ -63,6 +63,7 @@ public class ReactContext extends ContextWrapper { private @Nullable NativeModuleCallExceptionHandler mNativeModuleCallExceptionHandler; private @Nullable NativeModuleCallExceptionHandler mExceptionHandlerWrapper; private @Nullable WeakReference mCurrentActivity; + private boolean mIsInitialized = false; public ReactContext(Context base) { super(base); @@ -101,6 +102,18 @@ public class ReactContext extends ContextWrapper { mUiMessageQueueThread = queueConfig.getUIQueueThread(); mNativeModulesMessageQueueThread = queueConfig.getNativeModulesQueueThread(); mJSMessageQueueThread = queueConfig.getJSQueueThread(); + + /** TODO(T85807990): Fail fast if any of the threads is null. */ + if (mUiMessageQueueThread == null) { + throw new IllegalStateException("UI thread is null"); + } + if (mNativeModulesMessageQueueThread == null) { + throw new IllegalStateException("NativeModules thread is null"); + } + if (mJSMessageQueueThread == null) { + throw new IllegalStateException("JavaScript thread is null"); + } + mIsInitialized = true; } public void resetPerfStats() { @@ -352,10 +365,20 @@ public class ReactContext extends ContextWrapper { } public void assertOnNativeModulesQueueThread() { + /** TODO(T85807990): Fail fast if the ReactContext isn't initialized */ + if (!mIsInitialized) { + throw new IllegalStateException( + "Tried to call assertOnNativeModulesQueueThread() on an uninitialized ReactContext"); + } Assertions.assertNotNull(mNativeModulesMessageQueueThread).assertIsOnThread(); } public void assertOnNativeModulesQueueThread(String message) { + /** TODO(T85807990): Fail fast if the ReactContext isn't initialized */ + if (!mIsInitialized) { + throw new IllegalStateException( + "Tried to call assertOnNativeModulesQueueThread(message) on an uninitialized ReactContext"); + } Assertions.assertNotNull(mNativeModulesMessageQueueThread).assertIsOnThread(message); }