Made flipper plugins a little more robust
Summary: Added some assertions and string casts to make plugins a bit more robust Reviewed By: passy Differential Revision: D19427909 fbshipit-source-id: 46a3138805db865b538f745fae25ce1897e35736
This commit is contained in:
committed by
Facebook Github Bot
parent
db9c41303d
commit
28fd95589f
@@ -72,10 +72,14 @@ public class FlipperReactNativeJavaScriptPluginManager {
|
||||
}
|
||||
|
||||
public void send(String pluginId, String method, String data) {
|
||||
FlipperReactNativeJavaScriptPlugin plugin = getPlugin(pluginId);
|
||||
if (data == null) {
|
||||
plugin.getConnection().send(method, (FlipperObject) null);
|
||||
return;
|
||||
}
|
||||
// Optimization: throwing raw strings around to the desktop would probably avoid some double
|
||||
// parsing...
|
||||
Object parsedData = parseJSON(data);
|
||||
FlipperReactNativeJavaScriptPlugin plugin = getPlugin(pluginId);
|
||||
if (parsedData instanceof FlipperArray) {
|
||||
plugin.getConnection().send(method, (FlipperArray) parsedData);
|
||||
} else {
|
||||
@@ -134,14 +138,17 @@ public class FlipperReactNativeJavaScriptPluginManager {
|
||||
}
|
||||
|
||||
private static Object /* FlipperArray | FlipperObject */ parseJSON(String json) {
|
||||
if (json == null) {
|
||||
return null;
|
||||
}
|
||||
// returns either a FlipperObject or Flipper array, pending the data
|
||||
try {
|
||||
JSONTokener tokener = new JSONTokener(json);
|
||||
if (tokener.nextClean() == '[') {
|
||||
char firstChar = tokener.nextClean();
|
||||
tokener.back();
|
||||
if (firstChar == '[') {
|
||||
return new FlipperArray(new JSONArray(tokener));
|
||||
} else {
|
||||
tokener.back();
|
||||
return new FlipperObject(new JSONObject(tokener));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
|
||||
@@ -32,12 +32,14 @@ public class FlipperReactNativeJavaScriptReceiver implements FlipperReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(FlipperObject params, FlipperResponder responder) throws Exception {
|
||||
String responderId = manager.createResponderId(responder);
|
||||
WritableMap eventData = Arguments.createMap();
|
||||
eventData.putString("plugin", plugin);
|
||||
eventData.putString("method", method);
|
||||
eventData.putString("params", params.toJsonString());
|
||||
if (responder != null) {
|
||||
String responderId = manager.createResponderId(responder);
|
||||
eventData.putString("responderId", responderId);
|
||||
}
|
||||
module.sendJSEvent("react-native-flipper-receive-event", eventData);
|
||||
}
|
||||
}
|
||||
|
||||
31
react-native/react-native-flipper/index.js
vendored
31
react-native/react-native-flipper/index.js
vendored
@@ -17,6 +17,20 @@ export default Flipper;
|
||||
const listeners = {}; // plugin#method -> callback
|
||||
const plugins = {}; // plugin -> Plugin
|
||||
|
||||
function assertSerializable(data) {
|
||||
if (
|
||||
data === undefined ||
|
||||
Array.isArray(data) ||
|
||||
(data && typeof data === 'object')
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
throw new Error(
|
||||
'Flipper: Expected serializable (undefined, an array or an object). Got: ' +
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
||||
class Connection {
|
||||
connected;
|
||||
pluginId;
|
||||
@@ -30,15 +44,20 @@ class Connection {
|
||||
if (!this.connected) {
|
||||
throw new Error('Cannot send data, not connected');
|
||||
}
|
||||
assertSerializable(data);
|
||||
Flipper.send(this.pluginId, method, JSON.stringify(data));
|
||||
}
|
||||
|
||||
reportErrorWithMetadata(reason, stackTrace) {
|
||||
Flipper.reportErrorWithMetadata(this.pluginId, reason, stackTrace);
|
||||
Flipper.reportErrorWithMetadata(
|
||||
this.pluginId,
|
||||
'' + reason,
|
||||
'' + stackTrace,
|
||||
);
|
||||
}
|
||||
|
||||
reportError(error) {
|
||||
Flipper.reportError(this.pluginId, error);
|
||||
Flipper.reportError(this.pluginId, '' + error);
|
||||
}
|
||||
|
||||
receive(method, listener) {
|
||||
@@ -59,6 +78,7 @@ class Responder {
|
||||
}
|
||||
|
||||
success(response) {
|
||||
assertSerializable(response);
|
||||
Flipper.respondSuccess(
|
||||
this.responderId,
|
||||
response == null ? null : JSON.stringify(response),
|
||||
@@ -66,15 +86,13 @@ class Responder {
|
||||
}
|
||||
|
||||
error(response) {
|
||||
assertSerializable(response);
|
||||
Flipper.respondError(this.responderId, JSON.stringify(response));
|
||||
}
|
||||
}
|
||||
|
||||
function startEventListeners() {
|
||||
const emitter = new NativeEventEmitter(Flipper);
|
||||
emitter.removeAllListeners('react-native-flipper-plugin-connect');
|
||||
emitter.removeAllListeners('react-native-flipper-plugin-disconnect');
|
||||
emitter.removeAllListeners('react-native-flipper-receive-event');
|
||||
|
||||
emitter.addListener('react-native-flipper-plugin-connect', event => {
|
||||
const {plugin} = event;
|
||||
@@ -98,7 +116,8 @@ function startEventListeners() {
|
||||
const {plugin, method, params, responderId} = event;
|
||||
const key = plugin + '#' + method;
|
||||
if (listeners[key]) {
|
||||
const responder = new Responder(responderId);
|
||||
const responder =
|
||||
responderId != null ? new Responder(responderId) : undefined;
|
||||
listeners[key](JSON.parse(params), responder);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user