WebSocketModule should verify that Catalyst is alive before getting a JS module

Summary:
WebSocketModule can be called asynchronously while the ReactContext/CatalystInstance is being torn down. Trying to get a JS module at this time will result in a crash if the ReactContext has already torn down Catalyst. Check explicitly that Catalyst is still alive before trying to emit an event to JS via some JS module.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D18020359

fbshipit-source-id: 1b77abd457c7d97bd241389251890bb682b6fde3
This commit is contained in:
Joshua Gross
2019-10-19 02:30:09 -07:00
committed by Facebook Github Bot
parent 46a28e5460
commit 9ddc038e54
@@ -7,6 +7,7 @@
package com.facebook.react.modules.websocket;
import android.util.Log;
import androidx.annotation.Nullable;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.Arguments;
@@ -14,12 +15,14 @@ import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReactSoftException;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableMapKeySetIterator;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.common.build.ReactBuildConfig;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.modules.network.ForwardingCookieHandler;
@@ -61,9 +64,21 @@ public final class WebSocketModule extends ReactContextBaseJavaModule {
}
private void sendEvent(String eventName, WritableMap params) {
mReactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
if (mReactContext.hasActiveCatalystInstance()) {
mReactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
} else {
// We want to collect data about how often this happens, but raising a SoftException in Debug
// will cause a crash, which isn't desirable.
String msg =
"sendEvent: trying to update app state when Catalyst Instance has already disappeared";
if (ReactBuildConfig.DEBUG) {
Log.e(NAME, msg);
} else {
ReactSoftException.logSoftException(NAME, new IllegalStateException(msg));
}
}
}
@Override